diff options
Diffstat (limited to 'protocols')
| -rw-r--r-- | protocols/WhatsAppWeb/WhatsAppWeb.vcxproj | 11 | ||||
| -rw-r--r-- | protocols/WhatsAppWeb/WhatsAppWeb.vcxproj.filters | 53 | ||||
| -rw-r--r-- | protocols/WhatsAppWeb/res/version.rc | 48 | ||||
| -rw-r--r-- | protocols/WhatsAppWeb/res/whatsapp.rc | 118 | ||||
| -rw-r--r-- | protocols/WhatsAppWeb/src/avatars.cpp | 13 | ||||
| -rw-r--r-- | protocols/WhatsAppWeb/src/db.h | 61 | ||||
| -rw-r--r-- | protocols/WhatsAppWeb/src/main.cpp | 14 | ||||
| -rw-r--r-- | protocols/WhatsAppWeb/src/options.cpp | 8 | ||||
| -rw-r--r-- | protocols/WhatsAppWeb/src/proto.cpp | 68 | ||||
| -rw-r--r-- | protocols/WhatsAppWeb/src/proto.h | 31 | ||||
| -rw-r--r-- | protocols/WhatsAppWeb/src/resource.h | 8 | ||||
| -rw-r--r-- | protocols/WhatsAppWeb/src/server.cpp | 151 | ||||
| -rw-r--r-- | protocols/WhatsAppWeb/src/stdafx.cxx | 12 | ||||
| -rw-r--r-- | protocols/WhatsAppWeb/src/stdafx.h | 21 | ||||
| -rw-r--r-- | protocols/WhatsAppWeb/src/version.h | 2 | 
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            ""  | 
