From 6d932bfaf11e4699355fedc45e28b353b8877130 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Thu, 18 Sep 2014 21:52:10 +0000 Subject: merge into trunk git-svn-id: http://svn.miranda-ng.org/main/trunk@10515 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/WhatsApp/src/proto.cpp | 301 ++++++++++++++++----------------------- 1 file changed, 121 insertions(+), 180 deletions(-) (limited to 'protocols/WhatsApp/src/proto.cpp') diff --git a/protocols/WhatsApp/src/proto.cpp b/protocols/WhatsApp/src/proto.cpp index 4b142f0d47..634ac19c05 100644 --- a/protocols/WhatsApp/src/proto.cpp +++ b/protocols/WhatsApp/src/proto.cpp @@ -1,9 +1,11 @@ #include "common.h" +#include "WhatsAPI++\WARegister.h" + WhatsAppProto::WhatsAppProto(const char* proto_name, const TCHAR* username) : PROTO(proto_name, username) { - this->challenge = new std::vector; + this->challenge = new std::vector < unsigned char > ; this->msgId = 0; this->msgIdHeader = time(NULL); @@ -22,20 +24,18 @@ WhatsAppProto::WhatsAppProto(const char* proto_name, const TCHAR* username) : // Create standard network connection TCHAR descr[512]; - NETLIBUSER nlu = {sizeof(nlu)}; + NETLIBUSER nlu = { sizeof(nlu) }; nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS | NUF_TCHAR; - char module[512]; - mir_snprintf(module, SIZEOF(module), "%s", m_szModuleName); - nlu.szSettingsModule = module; + nlu.szSettingsModule = m_szModuleName; mir_sntprintf(descr, SIZEOF(descr), TranslateT("%s server connection"), m_tszUserName); nlu.ptszDescriptiveName = descr; - m_hNetlibUser = (HANDLE) CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM) &nlu); + m_hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); if (m_hNetlibUser == NULL) MessageBox(NULL, TranslateT("Unable to get Netlib connection for WhatsApp"), m_tszUserName, MB_OK); WASocketConnection::initNetwork(m_hNetlibUser); - def_avatar_folder_ = std::tstring( VARST( _T("%miranda_avatarcache%"))) + _T("\\") + m_tszUserName; + def_avatar_folder_ = std::tstring(VARST(_T("%miranda_avatarcache%"))) + _T("\\") + m_tszUserName; SetAllContactStatuses(ID_STATUS_OFFLINE, true); } @@ -61,51 +61,40 @@ int WhatsAppProto::OnModulesLoaded(WPARAM wParam, LPARAM lParam) return 0; } -DWORD_PTR WhatsAppProto::GetCaps( int type, MCONTACT hContact ) +DWORD_PTR WhatsAppProto::GetCaps(int type, MCONTACT hContact) { - switch(type) - { - case PFLAGNUM_1: - { - DWORD_PTR flags = PF1_IM | PF1_CHAT | PF1_BASICSEARCH | PF1_ADDSEARCHRES; - return flags | PF1_MODEMSGRECV; // #TODO - } - case PFLAGNUM_2: - return PF2_ONLINE | PF2_INVISIBLE; - case PFLAGNUM_3: - return 0; - case PFLAGNUM_4: - return PF4_NOCUSTOMAUTH | PF4_IMSENDUTF | PF4_FORCEADDED | PF4_NOAUTHDENYREASON | PF4_IMSENDOFFLINE | PF4_NOAUTHDENYREASON | PF4_SUPPORTTYPING | PF4_AVATARS; - case PFLAGNUM_5: - return 0; - case PFLAG_MAXLENOFMESSAGE: - return 500; // #TODO - case PFLAG_UNIQUEIDTEXT: - return (DWORD_PTR) "WhatsApp ID"; - case PFLAG_UNIQUEIDSETTING: - return (DWORD_PTR) "ID"; + switch (type) { + case PFLAGNUM_1: + return PF1_IM | PF1_CHAT | PF1_BASICSEARCH | PF1_ADDSEARCHRES | PF1_MODEMSGRECV; + case PFLAGNUM_2: + return PF2_ONLINE | PF2_INVISIBLE; + case PFLAGNUM_3: + return 0; + case PFLAGNUM_4: + return PF4_NOCUSTOMAUTH | PF4_IMSENDUTF | PF4_FORCEADDED | PF4_NOAUTHDENYREASON | PF4_IMSENDOFFLINE | PF4_NOAUTHDENYREASON | PF4_SUPPORTTYPING | PF4_AVATARS; + case PFLAGNUM_5: + return 0; + case PFLAG_MAXLENOFMESSAGE: + return 500; // #TODO + case PFLAG_UNIQUEIDTEXT: + return (DWORD_PTR)"WhatsApp ID"; + case PFLAG_UNIQUEIDSETTING: + return (DWORD_PTR)"ID"; } return 0; } -int WhatsAppProto::SetStatus( int new_status ) +int WhatsAppProto::SetStatus(int new_status) { debugLogA("===== Beginning SetStatus process"); // Routing statuses not supported by WhatsApp - switch ( new_status ) - { + switch (new_status) { case ID_STATUS_INVISIBLE: case ID_STATUS_OFFLINE: m_iDesiredStatus = new_status; break; - /* - case ID_STATUS_CONNECTING: - m_iDesiredStatus = ID_STATUS_OFFLINE; - break; - */ - case ID_STATUS_IDLE: default: m_iDesiredStatus = ID_STATUS_INVISIBLE; @@ -117,19 +106,17 @@ int WhatsAppProto::SetStatus( int new_status ) break; } - if (m_iStatus == ID_STATUS_CONNECTING) - { + if (m_iStatus == ID_STATUS_CONNECTING) { debugLogA("===== Status is connecting, no change"); return 0; } - if (m_iStatus == m_iDesiredStatus) - { + if (m_iStatus == m_iDesiredStatus) { debugLogA("===== Statuses are same, no change"); return 0; } - ForkThread( &WhatsAppProto::ChangeStatus, this ); + ForkThread(&WhatsAppProto::ChangeStatus, this); return 0; } @@ -139,7 +126,7 @@ MCONTACT WhatsAppProto::AddToList(int flags, PROTOSEARCHRESULT* psr) return NULL; } -int WhatsAppProto::AuthRequest(MCONTACT hContact,const PROTOCHAR *message) +int WhatsAppProto::AuthRequest(MCONTACT hContact, const PROTOCHAR *message) { return this->RequestFriendship((WPARAM)hContact, NULL); } @@ -149,7 +136,7 @@ int WhatsAppProto::Authorize(HANDLE hDbEvent) return 1; } -HANDLE WhatsAppProto::SearchBasic( const PROTOCHAR* id ) +HANDLE WhatsAppProto::SearchBasic(const PROTOCHAR* id) { if (isOffline()) return 0; @@ -161,164 +148,143 @@ HANDLE WhatsAppProto::SearchBasic( const PROTOCHAR* id ) ///////////////////////////////////////////////////////////////////////////////////////// -static NETLIBHTTPHEADER s_registerHeaders[] = +static NETLIBHTTPHEADER s_registerHeaders[] = { - { "User-Agent", ACCOUNT_USER_AGENT_REGISTRATION }, - { "Accept", "text/json" }, + { "User-Agent", ACCOUNT_USER_AGENT }, + { "Accept", "text/json" }, { "Content-Type", "application/x-www-form-urlencoded" } }; -string WhatsAppProto::Register(int state, string cc, string number, string code) +string WhatsAppProto::Register(int state, const string &cc, const string &number, const string &code) { string idx; string ret; DBVARIANT dbv; - if ( WASocketConnection::hNetlibUser == NULL) - { + if (WASocketConnection::hNetlibUser == NULL) { NotifyEvent(m_tszUserName, TranslateT("Network-connection error."), NULL, WHATSAPP_EVENT_CLIENT); return ret; } - if ( !getString(WHATSAPP_KEY_IDX, &dbv)) - { + if (!getString(WHATSAPP_KEY_IDX, &dbv)) { idx = dbv.pszVal; db_free(&dbv); } - if (idx.empty()) - { + if (idx.empty()) { std::stringstream tm; tm << time(NULL); BYTE idxBuf[16]; utils::md5string(tm.str(), idxBuf); - idx = std::string((const char*) idxBuf, 16); + idx = std::string((const char*)idxBuf, 16); setString(WHATSAPP_KEY_IDX, idx.c_str()); } - string url; - if (state == REG_STATE_REQ_CODE) - { - unsigned char digest[16]; - utils::md5string(std::string(ACCOUNT_TOKEN_PREFIX1) + ACCOUNT_TOKEN_PREFIX2 + number, digest); - url = string(ACCOUNT_URL_CODEREQUESTV2); - url += "?lc=US&lg=en&mcc=000&mnc=000&method=sms&token=" + Utilities::bytesToHex(digest, 16); - } - else if (state == REG_STATE_REG_CODE) - { - url = string(ACCOUNT_URL_REGISTERREQUESTV2); - url += "?code="+ code; - } - url += "&cc="+ cc +"&in="+ number +"&id="+ idx; + CMStringA url = WARegister::RequestCodeUrl(cc + number, code); + if (url.IsEmpty()) + return ret; - NETLIBHTTPREQUEST nlhr = {sizeof(NETLIBHTTPREQUEST)}; + NETLIBHTTPREQUEST nlhr = { sizeof(NETLIBHTTPREQUEST) }; nlhr.requestType = REQUEST_POST; - nlhr.szUrl = (char*) url.c_str(); + nlhr.szUrl = url.GetBuffer(); nlhr.headers = s_registerHeaders; nlhr.headersCount = SIZEOF(s_registerHeaders); nlhr.flags = NLHRF_HTTP11 | NLHRF_GENERATEHOST | NLHRF_REMOVEHOST | NLHRF_SSL; - NETLIBHTTPREQUEST* pnlhr = (NETLIBHTTPREQUEST*) CallService(MS_NETLIB_HTTPTRANSACTION, - (WPARAM) WASocketConnection::hNetlibUser, (LPARAM)&nlhr); + NETLIBHTTPREQUEST* pnlhr = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, + (WPARAM)WASocketConnection::hNetlibUser, (LPARAM)&nlhr); - string title = this->TranslateStr("Registration"); + const TCHAR *ptszTitle = TranslateT("Registration"); if (pnlhr == NULL) { - this->NotifyEvent(title, this->TranslateStr("Registration failed. Invalid server response."), NULL, WHATSAPP_EVENT_CLIENT); + this->NotifyEvent(ptszTitle, TranslateT("Registration failed. Invalid server response."), NULL, WHATSAPP_EVENT_CLIENT); return ret; } debugLogA("Server response: %s", pnlhr->pData); - MessageBoxA(NULL, pnlhr->pData, "Debug", MB_OK); JSONROOT resp(pnlhr->pData); - if (resp == NULL) - { - this->NotifyEvent(title, this->TranslateStr("Registration failed. Invalid server response."), NULL, WHATSAPP_EVENT_CLIENT); + if (resp == NULL) { + this->NotifyEvent(ptszTitle, TranslateT("Registration failed. Invalid server response."), NULL, WHATSAPP_EVENT_CLIENT); return ret; } // Status = fail JSONNODE *val = json_get(resp, "status"); - if (!lstrcmp( ptrT(json_as_string(val)), _T("fail"))) - { + if (!lstrcmp(ptrT(json_as_string(val)), _T("fail"))) { JSONNODE *tmpVal = json_get(resp, "reason"); - if (!lstrcmp( ptrT(json_as_string(tmpVal)), _T("stale"))) - this->NotifyEvent(title, this->TranslateStr("Registration failed due to stale code. Please request a new code"), NULL, WHATSAPP_EVENT_CLIENT); + if (!lstrcmp(ptrT(json_as_string(tmpVal)), _T("stale"))) + this->NotifyEvent(ptszTitle, TranslateT("Registration failed due to stale code. Please request a new code"), NULL, WHATSAPP_EVENT_CLIENT); else - this->NotifyEvent(title, this->TranslateStr("Registration failed."), NULL, WHATSAPP_EVENT_CLIENT); + this->NotifyEvent(ptszTitle, TranslateT("Registration failed."), NULL, WHATSAPP_EVENT_CLIENT); tmpVal = json_get(resp, "retry_after"); - if (tmpVal != NULL) - this->NotifyEvent(title, this->TranslateStr("Please try again in %i seconds", json_as_int(tmpVal)), NULL, WHATSAPP_EVENT_OTHER); + if (tmpVal != NULL) { + CMString tmp(FORMAT, TranslateT("Please try again in %i seconds"), json_as_int(tmpVal)); + this->NotifyEvent(ptszTitle, tmp, NULL, WHATSAPP_EVENT_OTHER); + } + return ret; } // Request code - else if (state == REG_STATE_REQ_CODE) - { - if ( !lstrcmp( ptrT(json_as_string(val)), _T("sent"))) - this->NotifyEvent(title, this->TranslateStr("Registration code has been sent to your phone."), NULL, WHATSAPP_EVENT_OTHER); + if (state == REG_STATE_REQ_CODE) { + if (!lstrcmp(ptrT(json_as_string(val)), _T("sent"))) + this->NotifyEvent(ptszTitle, TranslateT("Registration code has been sent to your phone."), NULL, WHATSAPP_EVENT_OTHER); + return "ok"; } // Register - else if (state == REG_STATE_REG_CODE) - { + if (state == REG_STATE_REG_CODE) { val = json_get(resp, "pw"); if (val == NULL) - this->NotifyEvent(title, this->TranslateStr("Registration failed."), NULL, WHATSAPP_EVENT_CLIENT); + this->NotifyEvent(ptszTitle, TranslateT("Registration failed."), NULL, WHATSAPP_EVENT_CLIENT); else - ret = _T2A( ptrT(json_as_string(val))); + ret = _T2A(ptrT(json_as_string(val))); } - json_delete(resp); return ret; } ////////////////////////////////////////////////////////////////////////////// // EVENTS -INT_PTR WhatsAppProto::SvcCreateAccMgrUI(WPARAM wParam,LPARAM lParam) +INT_PTR WhatsAppProto::SvcCreateAccMgrUI(WPARAM wParam, LPARAM lParam) { - return (INT_PTR)CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_WHATSAPPACCOUNT), - (HWND)lParam, WhatsAppAccountProc, (LPARAM)this ); + return (INT_PTR)CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_WHATSAPOPTIONS), + (HWND)lParam, WhatsAppAccountProc, (LPARAM)this); } int WhatsAppProto::OnOptionsInit(WPARAM wParam, LPARAM lParam) { - OPTIONSDIALOGPAGE odp = {sizeof(odp)}; - odp.hInstance = g_hInstance; - odp.ptszTitle = m_tszUserName; + OPTIONSDIALOGPAGE odp = { sizeof(odp) }; + odp.hInstance = g_hInstance; + odp.ptszTitle = m_tszUserName; odp.dwInitParam = LPARAM(this); - odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR | ODPF_DONTTRANSLATE; + odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR | ODPF_DONTTRANSLATE; - odp.position = 1; - odp.ptszGroup = LPGENT("Network"); - odp.ptszTab = LPGENT("Account"); + odp.position = 1; + odp.ptszGroup = LPGENT("Network"); + odp.ptszTab = LPGENT("Account"); odp.pszTemplate = MAKEINTRESOURCEA(IDD_WHATSAPOPTIONS); - odp.pfnDlgProc = WhatsAppAccountProc; + odp.pfnDlgProc = WhatsAppAccountProc; Options_AddPage(wParam, &odp); return 0; } -int WhatsAppProto::RefreshBuddyList(WPARAM, LPARAM ) +int WhatsAppProto::RefreshBuddyList(WPARAM, LPARAM) { - debugLogA(""); - if (!isOffline()) - { + if (!isOffline()) { //ForkThread( } return 0; } -int WhatsAppProto::RequestFriendship(WPARAM wParam, LPARAM lParam) +int WhatsAppProto::RequestFriendship(WPARAM hContact, LPARAM lParam) { - if (wParam == NULL || isOffline()) + if (hContact == NULL || isOffline()) return 0; - MCONTACT hContact = MCONTACT(wParam); - DBVARIANT dbv; - if ( !getString(hContact, WHATSAPP_KEY_ID, &dbv)) - { + if (!getString(hContact, WHATSAPP_KEY_ID, &dbv)) { std::string id(dbv.pszVal); this->connection->sendQueryLastOnline(id); this->connection->sendPresenceSubscriptionRequest(id); @@ -335,29 +301,20 @@ std::tstring WhatsAppProto::GetAvatarFolder() LRESULT CALLBACK PopupDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - switch(message) - { + switch (message) { case WM_COMMAND: - { // After a click, destroy popup PUDeletePopup(hwnd); - } - break; + break; case WM_CONTEXTMENU: PUDeletePopup(hwnd); break; case UM_FREEPLUGINDATA: - { // After close, free - TCHAR* url = (TCHAR*)PUGetPluginData(hwnd); - if (url != NULL) - mir_free(url); - } return FALSE; - - default: - break; + mir_free(PUGetPluginData(hwnd)); + return FALSE; } return DefWindowProc(hwnd, message, wParam, lParam); @@ -365,49 +322,44 @@ LRESULT CALLBACK PopupDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa void WhatsAppProto::NotifyEvent(const string& title, const string& info, MCONTACT contact, DWORD flags, TCHAR* url) { - TCHAR* rawTitle = mir_a2t_cp(title.c_str(), CP_UTF8); - TCHAR* rawInfo = mir_a2t_cp(info.c_str(), CP_UTF8); + TCHAR *rawTitle = mir_a2t_cp(title.c_str(), CP_UTF8); + TCHAR *rawInfo = mir_a2t_cp(info.c_str(), CP_UTF8); this->NotifyEvent(rawTitle, rawInfo, contact, flags, url); mir_free(rawTitle); mir_free(rawInfo); } -void WhatsAppProto::NotifyEvent(TCHAR* title, TCHAR* info, MCONTACT contact, DWORD flags, TCHAR* szUrl) +void WhatsAppProto::NotifyEvent(const TCHAR *title, const TCHAR *info, MCONTACT contact, DWORD flags, TCHAR* szUrl) { int ret; int timeout; COLORREF colorBack = 0; COLORREF colorText = 0; - switch ( flags ) - { - case WHATSAPP_EVENT_CLIENT: - if ( !getByte( WHATSAPP_KEY_EVENT_CLIENT_ENABLE, DEFAULT_EVENT_CLIENT_ENABLE )) - goto exit; - if ( !getByte( WHATSAPP_KEY_EVENT_CLIENT_DEFAULT, 0 )) - { - colorBack = getDword( WHATSAPP_KEY_EVENT_CLIENT_COLBACK, DEFAULT_EVENT_COLBACK ); - colorText = getDword( WHATSAPP_KEY_EVENT_CLIENT_COLTEXT, DEFAULT_EVENT_COLTEXT ); - } - timeout = getDword( WHATSAPP_KEY_EVENT_CLIENT_TIMEOUT, 0 ); - flags |= NIIF_WARNING; - break; + switch (flags) { + case WHATSAPP_EVENT_CLIENT: + if (!getByte(WHATSAPP_KEY_EVENT_CLIENT_ENABLE, DEFAULT_EVENT_CLIENT_ENABLE)) + goto exit; + if (!getByte(WHATSAPP_KEY_EVENT_CLIENT_DEFAULT, 0)) { + colorBack = getDword(WHATSAPP_KEY_EVENT_CLIENT_COLBACK, DEFAULT_EVENT_COLBACK); + colorText = getDword(WHATSAPP_KEY_EVENT_CLIENT_COLTEXT, DEFAULT_EVENT_COLTEXT); + } + timeout = getDword(WHATSAPP_KEY_EVENT_CLIENT_TIMEOUT, 0); + flags |= NIIF_WARNING; + break; - case WHATSAPP_EVENT_OTHER: - if ( !getByte( WHATSAPP_KEY_EVENT_OTHER_ENABLE, DEFAULT_EVENT_OTHER_ENABLE )) - goto exit; - if ( !getByte( WHATSAPP_KEY_EVENT_OTHER_DEFAULT, 0 )) - { - colorBack = getDword( WHATSAPP_KEY_EVENT_OTHER_COLBACK, DEFAULT_EVENT_COLBACK ); - colorText = getDword( WHATSAPP_KEY_EVENT_OTHER_COLTEXT, DEFAULT_EVENT_COLTEXT ); - } - timeout = getDword( WHATSAPP_KEY_EVENT_OTHER_TIMEOUT, -1 ); - SkinPlaySound( "OtherEvent" ); - flags |= NIIF_INFO; - break; + case WHATSAPP_EVENT_OTHER: + if (!getByte(WHATSAPP_KEY_EVENT_OTHER_ENABLE, DEFAULT_EVENT_OTHER_ENABLE)) + goto exit; + if (!getByte(WHATSAPP_KEY_EVENT_OTHER_DEFAULT, 0)) { + colorBack = getDword(WHATSAPP_KEY_EVENT_OTHER_COLBACK, DEFAULT_EVENT_COLBACK); + colorText = getDword(WHATSAPP_KEY_EVENT_OTHER_COLTEXT, DEFAULT_EVENT_COLTEXT); + } + timeout = getDword(WHATSAPP_KEY_EVENT_OTHER_TIMEOUT, -1); + SkinPlaySound("OtherEvent"); + flags |= NIIF_INFO; + break; } - if ( !getByte(WHATSAPP_KEY_SYSTRAY_NOTIFY,DEFAULT_SYSTRAY_NOTIFY)) - { - if (ServiceExists(MS_POPUP_ADDPOPUP)) - { + if (!getByte(WHATSAPP_KEY_SYSTRAY_NOTIFY, DEFAULT_SYSTRAY_NOTIFY)) { + if (ServiceExists(MS_POPUP_ADDPOPUP)) { POPUPDATAT pd; pd.colorBack = colorBack; pd.colorText = colorText; @@ -423,21 +375,19 @@ void WhatsAppProto::NotifyEvent(TCHAR* title, TCHAR* info, MCONTACT contact, DWO if (ret == 0) return; } - } else { - if (ServiceExists(MS_CLIST_SYSTRAY_NOTIFY)) - { + } + else { + if (ServiceExists(MS_CLIST_SYSTRAY_NOTIFY)) { MIRANDASYSTRAYNOTIFY err; int niif_flags = flags; - REMOVE_FLAG( niif_flags, WHATSAPP_EVENT_CLIENT | - WHATSAPP_EVENT_NOTIFICATION | - WHATSAPP_EVENT_OTHER ); + REMOVE_FLAG(niif_flags, WHATSAPP_EVENT_CLIENT | WHATSAPP_EVENT_NOTIFICATION | WHATSAPP_EVENT_OTHER); err.szProto = m_szModuleName; err.cbSize = sizeof(err); err.dwInfoFlags = NIIF_INTERN_TCHAR | niif_flags; - err.tszInfoTitle = title; - err.tszInfo = info; + err.tszInfoTitle = (TCHAR*)title; + err.tszInfo = (TCHAR*)info; err.uTimeout = 1000 * timeout; - ret = CallService(MS_CLIST_SYSTRAY_NOTIFY, 0, (LPARAM) & err); + ret = CallService(MS_CLIST_SYSTRAY_NOTIFY, 0, (LPARAM)& err); if (ret == 0) goto exit; @@ -451,12 +401,3 @@ exit: if (szUrl != NULL) mir_free(szUrl); } - -string WhatsAppProto::TranslateStr(const char* str, ...) -{ - va_list ap; - va_start(ap, str); - string ret = Utilities::string_format(Translate(str), ap); - va_end(ap); - return ret; -} \ No newline at end of file -- cgit v1.2.3