From 48f4b68ffcb66611a4294ed0fd0ac4e49dedb09d Mon Sep 17 00:00:00 2001 From: Kirill Volinsky Date: Sat, 8 Jun 2013 14:51:53 +0000 Subject: 3 spaces changed to 1 tab git-svn-id: http://svn.miranda-ng.org/main/trunk@4902 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/WhatsApp/src/WASocketConnection.cpp | 70 +- protocols/WhatsApp/src/cJSON.cpp | 38 +- protocols/WhatsApp/src/chat.cpp | 22 +- protocols/WhatsApp/src/connection.cpp | 330 ++++----- protocols/WhatsApp/src/contacts.cpp | 974 +++++++++++++------------- protocols/WhatsApp/src/dialogs.cpp | 130 ++-- protocols/WhatsApp/src/main.cpp | 8 +- protocols/WhatsApp/src/messages.cpp | 250 +++---- protocols/WhatsApp/src/proto.cpp | 437 ++++++------ protocols/WhatsApp/src/theme.cpp | 286 ++++---- protocols/WhatsApp/src/utils.cpp | 66 +- 11 files changed, 1305 insertions(+), 1306 deletions(-) (limited to 'protocols/WhatsApp') diff --git a/protocols/WhatsApp/src/WASocketConnection.cpp b/protocols/WhatsApp/src/WASocketConnection.cpp index 44c1a7d33b..15397f9932 100644 --- a/protocols/WhatsApp/src/WASocketConnection.cpp +++ b/protocols/WhatsApp/src/WASocketConnection.cpp @@ -5,7 +5,7 @@ HANDLE WASocketConnection::hNetlibUser = NULL; void WASocketConnection::initNetwork(HANDLE hNetlibUser) throw (WAException) { - WASocketConnection::hNetlibUser = hNetlibUser; + WASocketConnection::hNetlibUser = hNetlibUser; } void WASocketConnection::quitNetwork() { @@ -13,16 +13,16 @@ void WASocketConnection::quitNetwork() { WASocketConnection::WASocketConnection(const std::string& dir, int port) throw (WAException) { - NETLIBOPENCONNECTION noc = {sizeof(noc)}; - noc.szHost = dir.c_str(); - noc.wPort = port; - noc.flags = NLOCF_V2; // | NLOCF_SSL; - this->hConn = (HANDLE) CallService(MS_NETLIB_OPENCONNECTION, reinterpret_cast(this->hNetlibUser), - reinterpret_cast(&noc)); - if (this->hConn == NULL) - { - throw WAException(getLastErrorMsg(), WAException::SOCKET_EX, WAException::SOCKET_EX_OPEN); - } + NETLIBOPENCONNECTION noc = {sizeof(noc)}; + noc.szHost = dir.c_str(); + noc.wPort = port; + noc.flags = NLOCF_V2; // | NLOCF_SSL; + this->hConn = (HANDLE) CallService(MS_NETLIB_OPENCONNECTION, reinterpret_cast(this->hNetlibUser), + reinterpret_cast(&noc)); + if (this->hConn == NULL) + { + throw WAException(getLastErrorMsg(), WAException::SOCKET_EX, WAException::SOCKET_EX_OPEN); + } this->connected = true; } @@ -31,12 +31,12 @@ void WASocketConnection::write(int i) { char buffer; buffer = (char) i; - NETLIBBUFFER nlb; - nlb.buf = &buffer; - nlb.len = 1; - nlb.flags = MSG_NOHTTPGATEWAYWRAP | MSG_NODUMP; + NETLIBBUFFER nlb; + nlb.buf = &buffer; + nlb.len = 1; + nlb.flags = MSG_NOHTTPGATEWAYWRAP | MSG_NODUMP; - int result = CallService(MS_NETLIB_SEND, reinterpret_cast(this->hConn), reinterpret_cast(&nlb)); + int result = CallService(MS_NETLIB_SEND, reinterpret_cast(this->hConn), reinterpret_cast(&nlb)); if (result < 1) { throw WAException(getLastErrorMsg(), WAException::SOCKET_EX, WAException::SOCKET_EX_SEND); } @@ -48,8 +48,8 @@ void WASocketConnection::makeNonBlock() { } int WASocketConnection::waitForRead() { - // #TODO Is this called at all? - return 0; + // #TODO Is this called at all? + return 0; fd_set rfds; struct timeval tv; @@ -78,14 +78,14 @@ void WASocketConnection::flush() {} void WASocketConnection::write(const std::vector& bytes, int offset, int length) { - NETLIBBUFFER nlb; - std::string tmpBuf = std::string(bytes.begin(), bytes.end()); - nlb.buf = (char*) &(tmpBuf.c_str()[offset]); - nlb.len = length; - nlb.flags = 0; //MSG_NOHTTPGATEWAYWRAP | MSG_NODUMP; - - int result = CallService(MS_NETLIB_SEND, reinterpret_cast(this->hConn), - reinterpret_cast(&nlb)); + NETLIBBUFFER nlb; + std::string tmpBuf = std::string(bytes.begin(), bytes.end()); + nlb.buf = (char*) &(tmpBuf.c_str()[offset]); + nlb.len = length; + nlb.flags = 0; //MSG_NOHTTPGATEWAYWRAP | MSG_NODUMP; + + int result = CallService(MS_NETLIB_SEND, reinterpret_cast(this->hConn), + reinterpret_cast(&nlb)); if (result < length) { throw WAException(getLastErrorMsg(), WAException::SOCKET_EX, WAException::SOCKET_EX_SEND); } @@ -93,17 +93,17 @@ void WASocketConnection::write(const std::vector& bytes, int offs void WASocketConnection::write(const std::vector& bytes, int length) { - this->write(bytes, 0, length); + this->write(bytes, 0, length); } unsigned char WASocketConnection::read() { char c; - SetLastError(0); - int result; - //do { - result = Netlib_Recv(this->hConn, &c, 1, 0 /*MSG_NOHTTPGATEWAYWRAP | MSG_NODUMP*/); - //} while (WSAGetLastError() == EINTR); + SetLastError(0); + int result; + //do { + result = Netlib_Recv(this->hConn, &c, 1, 0 /*MSG_NOHTTPGATEWAYWRAP | MSG_NODUMP*/); + //} while (WSAGetLastError() == EINTR); if (result <= 0) { throw WAException(getLastErrorMsg(), WAException::SOCKET_EX, WAException::SOCKET_EX_RECV); } @@ -114,7 +114,7 @@ int WASocketConnection::read(std::vector& b, int off, int length) if (off < 0 || length < 0) { throw new WAException("Out of bounds", WAException::SOCKET_EX, WAException::SOCKET_EX_RECV); } - char* buffer = new char[length]; + char* buffer = new char[length]; int result = Netlib_Recv(this->hConn, buffer, length, MSG_NOHTTPGATEWAYWRAP | MSG_NODUMP); if (result <= 0) { @@ -124,13 +124,13 @@ int WASocketConnection::read(std::vector& b, int off, int length) for (int i = 0; i < result; i++) b[off + i] = buffer[i]; - delete[] buffer; + delete[] buffer; return result; } void WASocketConnection::forceShutdown() { - Netlib_Shutdown(this->hConn); + Netlib_Shutdown(this->hConn); } WASocketConnection::~WASocketConnection() { diff --git a/protocols/WhatsApp/src/cJSON.cpp b/protocols/WhatsApp/src/cJSON.cpp index a1f326bbe7..b65468fc7b 100644 --- a/protocols/WhatsApp/src/cJSON.cpp +++ b/protocols/WhatsApp/src/cJSON.cpp @@ -49,22 +49,22 @@ static void (*cJSON_free)(void *ptr) = free; static char* cJSON_strdup(const char* str) { - size_t len; - char* copy; + size_t len; + char* copy; - len = strlen(str) + 1; - if (!(copy = (char*)cJSON_malloc(len))) return 0; - memcpy(copy,str,len); - return copy; + len = strlen(str) + 1; + if (!(copy = (char*)cJSON_malloc(len))) return 0; + memcpy(copy,str,len); + return copy; } void cJSON_InitHooks(cJSON_Hooks* hooks) { - if (!hooks) { /* Reset hooks */ - cJSON_malloc = malloc; - cJSON_free = free; - return; - } + if (!hooks) { /* Reset hooks */ + cJSON_malloc = malloc; + cJSON_free = free; + return; + } cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc; cJSON_free = (hooks->free_fn)?hooks->free_fn:free; @@ -254,7 +254,7 @@ cJSON *cJSON_Parse(const char *value) { cJSON *c=cJSON_New_Item(); ep=0; - if (!c) return 0; /* memory fail */ + if (!c) return 0; /* memory fail */ if (!parse_value(c,skip(value))) {cJSON_Delete(c);return 0;} return c; @@ -471,7 +471,7 @@ static char *print_object(cJSON *item,int depth,int fmt) } /* Get Array size/item / object item. */ -int cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;} +int cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;} cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;} cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;} @@ -481,22 +481,22 @@ static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=p static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;} /* Add item to array/object. */ -void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}} -void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);} +void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}} +void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);} void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));} void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));} cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0; if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;} -void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));} +void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));} cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;} -void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));} +void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));} /* Replace array/object items with new ones. */ -void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return; +void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return; newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem; if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);} -void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}} +void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}} /* Create basic types: */ cJSON *cJSON_CreateNull() {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;} diff --git a/protocols/WhatsApp/src/chat.cpp b/protocols/WhatsApp/src/chat.cpp index a53a5077ca..e365a93e62 100644 --- a/protocols/WhatsApp/src/chat.cpp +++ b/protocols/WhatsApp/src/chat.cpp @@ -4,12 +4,12 @@ int WhatsAppProto::OnJoinChat(WPARAM,LPARAM) { - return 0; + return 0; } int WhatsAppProto::OnLeaveChat(WPARAM,LPARAM) { - return 0; + return 0; } int WhatsAppProto::OnChatOutgoing(WPARAM wParam, LPARAM lParam) @@ -35,13 +35,13 @@ int WhatsAppProto::OnChatOutgoing(WPARAM wParam, LPARAM lParam) mir_free(id); if (isOnline()) { - HANDLE hContact = this->ContactIDToHContact(chat_id); - if (hContact) - { - LOG("**Chat - Outgoing message: %s", text); - this->SendMsg(hContact, IS_CHAT, msg.c_str()); - - // #TODO Move to SendMsgWorker, otherwise all messages are "acknowledged" by Miranda + HANDLE hContact = this->ContactIDToHContact(chat_id); + if (hContact) + { + LOG("**Chat - Outgoing message: %s", text); + this->SendMsg(hContact, IS_CHAT, msg.c_str()); + + // #TODO Move to SendMsgWorker, otherwise all messages are "acknowledged" by Miranda GCDEST gcd = { m_szModuleName, { NULL }, GC_EVENT_MESSAGE }; gcd.ptszID = hook->pDest->ptszID; @@ -58,8 +58,8 @@ int WhatsAppProto::OnChatOutgoing(WPARAM wParam, LPARAM lParam) CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce); mir_free((void*)gce.ptszUID); - mir_free((void*)gce.ptszNick); - } + mir_free((void*)gce.ptszNick); + } } break; diff --git a/protocols/WhatsApp/src/connection.cpp b/protocols/WhatsApp/src/connection.cpp index 12d9e95508..7ec41e27e4 100644 --- a/protocols/WhatsApp/src/connection.cpp +++ b/protocols/WhatsApp/src/connection.cpp @@ -2,40 +2,40 @@ void WhatsAppProto::ChangeStatus(void*) { - if (m_iDesiredStatus != ID_STATUS_OFFLINE && m_iStatus == ID_STATUS_OFFLINE) - { - ResetEvent(update_loop_lock_); - ForkThread(&WhatsAppProto::sentinelLoop, this); - ForkThread(&WhatsAppProto::stayConnectedLoop, this); - } - else if (m_iStatus == ID_STATUS_INVISIBLE && m_iDesiredStatus == ID_STATUS_ONLINE) - { - if (this->connection != NULL) - { - this->connection->sendAvailableForChat(); - m_iStatus = ID_STATUS_ONLINE; - ProtoBroadcastAck(m_szModuleName, 0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) m_iStatus, ID_STATUS_INVISIBLE); - } - } - else if (m_iStatus == ID_STATUS_ONLINE && m_iDesiredStatus == ID_STATUS_INVISIBLE) - { - if (this->connection != NULL) - { - this->connection->sendClose(); - m_iStatus = ID_STATUS_INVISIBLE; - SetAllContactStatuses( ID_STATUS_OFFLINE, true ); - ProtoBroadcastAck(m_szModuleName, 0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) m_iStatus, ID_STATUS_ONLINE); - } - } - else if (m_iDesiredStatus == ID_STATUS_OFFLINE) - { - if (this->conn != NULL) - { - SetEvent(update_loop_lock_); - this->conn->forceShutdown(); - LOG("Forced shutdown"); - } - } + if (m_iDesiredStatus != ID_STATUS_OFFLINE && m_iStatus == ID_STATUS_OFFLINE) + { + ResetEvent(update_loop_lock_); + ForkThread(&WhatsAppProto::sentinelLoop, this); + ForkThread(&WhatsAppProto::stayConnectedLoop, this); + } + else if (m_iStatus == ID_STATUS_INVISIBLE && m_iDesiredStatus == ID_STATUS_ONLINE) + { + if (this->connection != NULL) + { + this->connection->sendAvailableForChat(); + m_iStatus = ID_STATUS_ONLINE; + ProtoBroadcastAck(m_szModuleName, 0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) m_iStatus, ID_STATUS_INVISIBLE); + } + } + else if (m_iStatus == ID_STATUS_ONLINE && m_iDesiredStatus == ID_STATUS_INVISIBLE) + { + if (this->connection != NULL) + { + this->connection->sendClose(); + m_iStatus = ID_STATUS_INVISIBLE; + SetAllContactStatuses( ID_STATUS_OFFLINE, true ); + ProtoBroadcastAck(m_szModuleName, 0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) m_iStatus, ID_STATUS_ONLINE); + } + } + else if (m_iDesiredStatus == ID_STATUS_OFFLINE) + { + if (this->conn != NULL) + { + SetEvent(update_loop_lock_); + this->conn->forceShutdown(); + LOG("Forced shutdown"); + } + } } void WhatsAppProto::stayConnectedLoop(void*) @@ -48,183 +48,183 @@ void WhatsAppProto::stayConnectedLoop(void*) { cc = dbv.pszVal; db_free(&dbv); - error = cc.empty(); + error = cc.empty(); } - if (error) + if (error) { NotifyEvent(m_tszUserName,TranslateT("Please enter a country-code."),NULL,WHATSAPP_EVENT_CLIENT); - return; + return; } - error = true; + error = true; if ( !db_get_s(NULL,m_szModuleName,WHATSAPP_KEY_LOGIN,&dbv,DBVT_ASCIIZ)) { in = dbv.pszVal; db_free(&dbv); - error = in.empty(); + error = in.empty(); } if (error) { NotifyEvent(m_tszUserName,TranslateT("Please enter a phone-number without country code."),NULL,WHATSAPP_EVENT_CLIENT); - return; + return; } - this->phoneNumber = cc + in; - this->jid = this->phoneNumber + "@s.whatsapp.net"; + this->phoneNumber = cc + in; + this->jid = this->phoneNumber + "@s.whatsapp.net"; - error = true; + error = true; if ( !db_get_s(NULL, m_szModuleName, WHATSAPP_KEY_NICK, &dbv, DBVT_ASCIIZ)) { this->nick = dbv.pszVal; db_free(&dbv); - error = nick.empty(); + error = nick.empty(); } if (error) { NotifyEvent(m_tszUserName, TranslateT("Please enter a nickname."), NULL, WHATSAPP_EVENT_CLIENT); - return; + return; } - error = true; + error = true; if ( !db_get_s(NULL,m_szModuleName,WHATSAPP_KEY_PASS,&dbv, DBVT_ASCIIZ)) { CallService(MS_DB_CRYPT_DECODESTRING,strlen(dbv.pszVal)+1, reinterpret_cast(dbv.pszVal)); pass = dbv.pszVal; db_free(&dbv); - error = pass.empty(); + error = pass.empty(); } if (error) { NotifyEvent(m_tszUserName,TranslateT("Please enter a password."),NULL,WHATSAPP_EVENT_CLIENT); - return; + return; } - // ----------------------------- - - Mutex writerMutex; - WALogin* login = NULL; - int desiredStatus; - - this->conn = NULL; - - while (true) - { - if (connection != NULL) - { - if (connection->getLogin() == NULL && login != NULL) - { - delete login; - login = NULL; - } - delete connection; - connection = NULL; - } - if (this->conn != NULL) - { - delete this->conn; - this->conn = NULL; - } - - desiredStatus = this->m_iDesiredStatus; - if (desiredStatus == ID_STATUS_OFFLINE || error) - { - LOG("Set status to offline"); - SetAllContactStatuses( ID_STATUS_OFFLINE, true ); - this->ToggleStatusMenuItems(false); - int prevStatus = this->m_iStatus; - this->m_iStatus = ID_STATUS_OFFLINE; - ProtoBroadcastAck(m_szModuleName, 0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) m_iStatus, prevStatus); - break; - } - - LOG("Connecting..."); - this->m_iStatus = ID_STATUS_CONNECTING; - ProtoBroadcastAck(m_szModuleName, 0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) ID_STATUS_OFFLINE, m_iStatus); - - CODE_BLOCK_TRY - - this->conn = new WASocketConnection("c.whatsapp.net", 5222); - - connection = new WAConnection(&this->connMutex, this, this); + // ----------------------------- + + Mutex writerMutex; + WALogin* login = NULL; + int desiredStatus; + + this->conn = NULL; + + while (true) + { + if (connection != NULL) + { + if (connection->getLogin() == NULL && login != NULL) + { + delete login; + login = NULL; + } + delete connection; + connection = NULL; + } + if (this->conn != NULL) + { + delete this->conn; + this->conn = NULL; + } + + desiredStatus = this->m_iDesiredStatus; + if (desiredStatus == ID_STATUS_OFFLINE || error) + { + LOG("Set status to offline"); + SetAllContactStatuses( ID_STATUS_OFFLINE, true ); + this->ToggleStatusMenuItems(false); + int prevStatus = this->m_iStatus; + this->m_iStatus = ID_STATUS_OFFLINE; + ProtoBroadcastAck(m_szModuleName, 0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) m_iStatus, prevStatus); + break; + } + + LOG("Connecting..."); + this->m_iStatus = ID_STATUS_CONNECTING; + ProtoBroadcastAck(m_szModuleName, 0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE) ID_STATUS_OFFLINE, m_iStatus); + + CODE_BLOCK_TRY + + this->conn = new WASocketConnection("c.whatsapp.net", 5222); + + connection = new WAConnection(&this->connMutex, this, this); login = new WALogin(connection, new BinTreeNodeReader(connection, conn, WAConnection::dictionary, WAConnection::DICTIONARY_LEN), new BinTreeNodeWriter(connection, conn, WAConnection::dictionary, WAConnection::DICTIONARY_LEN, &writerMutex), - "s.whatsapp.net", this->phoneNumber, std::string(ACCOUNT_RESOURCE) +"-5222", base64_decode(pass), nick); + "s.whatsapp.net", this->phoneNumber, std::string(ACCOUNT_RESOURCE) +"-5222", base64_decode(pass), nick); - std::vector* nextChallenge = login->login(*this->challenge); - delete this->challenge; - this->challenge = nextChallenge; - connection->setLogin(login); - connection->setVerboseId(true); // ? - if (desiredStatus != ID_STATUS_INVISIBLE) { - connection->sendAvailableForChat(); - } - - LOG("Set status to online"); - this->m_iStatus = desiredStatus; - ProtoBroadcastAck(m_szModuleName, 0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE )m_iStatus, ID_STATUS_CONNECTING); - this->ToggleStatusMenuItems(true); - - ForkThread(&WhatsAppProto::ProcessBuddyList, this); - - // #TODO Move out of try block. Exception is expected on disconnect - bool cont = true; - while (cont == true) - { - this->lastPongTime = time(NULL); - cont = connection->read(); - } - LOG("Exit from read-loop"); - - CODE_BLOCK_CATCH(WAException) - error = true; - CODE_BLOCK_CATCH(exception) - error = true; - CODE_BLOCK_CATCH_UNKNOWN - error = true; - CODE_BLOCK_END - } - LOG("Break out from loop"); + std::vector* nextChallenge = login->login(*this->challenge); + delete this->challenge; + this->challenge = nextChallenge; + connection->setLogin(login); + connection->setVerboseId(true); // ? + if (desiredStatus != ID_STATUS_INVISIBLE) { + connection->sendAvailableForChat(); + } + + LOG("Set status to online"); + this->m_iStatus = desiredStatus; + ProtoBroadcastAck(m_szModuleName, 0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE )m_iStatus, ID_STATUS_CONNECTING); + this->ToggleStatusMenuItems(true); + + ForkThread(&WhatsAppProto::ProcessBuddyList, this); + + // #TODO Move out of try block. Exception is expected on disconnect + bool cont = true; + while (cont == true) + { + this->lastPongTime = time(NULL); + cont = connection->read(); + } + LOG("Exit from read-loop"); + + CODE_BLOCK_CATCH(WAException) + error = true; + CODE_BLOCK_CATCH(exception) + error = true; + CODE_BLOCK_CATCH_UNKNOWN + error = true; + CODE_BLOCK_END + } + LOG("Break out from loop"); } void WhatsAppProto::sentinelLoop(void*) { - int delay = MAX_SILENT_INTERVAL; - int quietInterval; - while (WaitForSingleObjectEx(update_loop_lock_, delay * 1000, true) == WAIT_TIMEOUT) - { - if (this->m_iStatus != ID_STATUS_OFFLINE && this->connection != NULL && this->m_iDesiredStatus == this->m_iStatus) - { - // #TODO Quiet after pong or tree read? - quietInterval = difftime(time(NULL), this->lastPongTime); - if (quietInterval >= MAX_SILENT_INTERVAL) - { - CODE_BLOCK_TRY - LOG("send ping"); - this->lastPongTime = time(NULL); - this->connection->sendPing(); - CODE_BLOCK_CATCH(exception) - CODE_BLOCK_END - } - else - { - delay = MAX_SILENT_INTERVAL - quietInterval; - } - } - else - { - delay = MAX_SILENT_INTERVAL; - } - } - ResetEvent(update_loop_lock_); - LOG("Exiting sentinel loop"); + int delay = MAX_SILENT_INTERVAL; + int quietInterval; + while (WaitForSingleObjectEx(update_loop_lock_, delay * 1000, true) == WAIT_TIMEOUT) + { + if (this->m_iStatus != ID_STATUS_OFFLINE && this->connection != NULL && this->m_iDesiredStatus == this->m_iStatus) + { + // #TODO Quiet after pong or tree read? + quietInterval = difftime(time(NULL), this->lastPongTime); + if (quietInterval >= MAX_SILENT_INTERVAL) + { + CODE_BLOCK_TRY + LOG("send ping"); + this->lastPongTime = time(NULL); + this->connection->sendPing(); + CODE_BLOCK_CATCH(exception) + CODE_BLOCK_END + } + else + { + delay = MAX_SILENT_INTERVAL - quietInterval; + } + } + else + { + delay = MAX_SILENT_INTERVAL; + } + } + ResetEvent(update_loop_lock_); + LOG("Exiting sentinel loop"); } void WhatsAppProto::onPing(const std::string& id) { - if (this->isOnline()) { - CODE_BLOCK_TRY - LOG("Sending pong with id %s", id.c_str()); - this->connection->sendPong(id); - CODE_BLOCK_CATCH_ALL - } + if (this->isOnline()) { + CODE_BLOCK_TRY + LOG("Sending pong with id %s", id.c_str()); + this->connection->sendPong(id); + CODE_BLOCK_CATCH_ALL + } } diff --git a/protocols/WhatsApp/src/contacts.cpp b/protocols/WhatsApp/src/contacts.cpp index f412d6be56..8e5861efb6 100644 --- a/protocols/WhatsApp/src/contacts.cpp +++ b/protocols/WhatsApp/src/contacts.cpp @@ -15,7 +15,7 @@ bool WhatsAppProto::IsMyContact(HANDLE hContact, bool include_chat) } HANDLE WhatsAppProto::AddToContactList(const std::string& jid, BYTE type, bool dont_check, const char *new_name, - bool isChatRoom, bool isHidden) + bool isChatRoom, bool isHidden) { HANDLE hContact; @@ -24,34 +24,34 @@ HANDLE WhatsAppProto::AddToContactList(const std::string& jid, BYTE type, bool d hContact = ContactIDToHContact(jid); if( hContact ) - { - if (new_name != NULL) - { - DBVARIANT dbv; - string oldName; - if (db_get_s(hContact, m_szModuleName, WHATSAPP_KEY_PUSH_NAME, &dbv, DBVT_UTF8)) - { - oldName = jid.c_str(); - } - else - { - oldName = dbv.pszVal; - db_free(&dbv); - } - db_set_utf(hContact, m_szModuleName, WHATSAPP_KEY_PUSH_NAME, new_name); - - if (oldName.compare(string(new_name)) != 0) - { - this->NotifyEvent(oldName.c_str(), this->TranslateStr("is now known as '%s'", new_name), - hContact, WHATSAPP_EVENT_OTHER); - } - } - if (db_get_b(hContact, "CList", "Hidden", 0) > 0) - { - db_unset(hContact, "CList", "Hidden"); - } + { + if (new_name != NULL) + { + DBVARIANT dbv; + string oldName; + if (db_get_s(hContact, m_szModuleName, WHATSAPP_KEY_PUSH_NAME, &dbv, DBVT_UTF8)) + { + oldName = jid.c_str(); + } + else + { + oldName = dbv.pszVal; + db_free(&dbv); + } + db_set_utf(hContact, m_szModuleName, WHATSAPP_KEY_PUSH_NAME, new_name); + + if (oldName.compare(string(new_name)) != 0) + { + this->NotifyEvent(oldName.c_str(), this->TranslateStr("is now known as '%s'", new_name), + hContact, WHATSAPP_EVENT_OTHER); + } + } + if (db_get_b(hContact, "CList", "Hidden", 0) > 0) + { + db_unset(hContact, "CList", "Hidden"); + } return hContact; - } + } } // If not, make a new contact! @@ -61,37 +61,37 @@ HANDLE WhatsAppProto::AddToContactList(const std::string& jid, BYTE type, bool d if (CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)m_szModuleName) == 0) { db_set_s(hContact ,m_szModuleName, "ID", jid.c_str()); - LOG("Added contact %s", jid.c_str()); + LOG("Added contact %s", jid.c_str()); db_set_s(hContact, m_szModuleName, "MirVer", "WhatsApp"); db_unset(hContact, "CList", "MyHandle"); - db_set_b(hContact, "CList", "NotOnList", 1); - - /* - std::string newNameStr; - if (hasNickName) - { - newNameStr = new_name; - } - - DBEVENTINFO dbei = {0}; - dbei.cbSize = sizeof(dbei); - dbei.szModule = m_szModuleName; - dbei.timestamp = time(NULL); - dbei.flags = DBEF_UTF; - dbei.eventType = EVENTTYPE_ADDED; - dbei.cbBlob = sizeof(DWORD) * 2 + newNameStr.length() + 5; + db_set_b(hContact, "CList", "NotOnList", 1); + + /* + std::string newNameStr; + if (hasNickName) + { + newNameStr = new_name; + } + + DBEVENTINFO dbei = {0}; + dbei.cbSize = sizeof(dbei); + dbei.szModule = m_szModuleName; + dbei.timestamp = time(NULL); + dbei.flags = DBEF_UTF; + dbei.eventType = EVENTTYPE_ADDED; + dbei.cbBlob = sizeof(DWORD) * 2 + newNameStr.length() + 5; PBYTE pCurBlob = dbei.pBlob = ( PBYTE ) mir_alloc( dbei.cbBlob ); - *(PDWORD)pCurBlob = 0; pCurBlob += sizeof(DWORD); // UID - *(PDWORD)pCurBlob = (DWORD)hContact; pCurBlob += sizeof(DWORD); // Contact Handle + *(PDWORD)pCurBlob = 0; pCurBlob += sizeof(DWORD); // UID + *(PDWORD)pCurBlob = (DWORD)hContact; pCurBlob += sizeof(DWORD); // Contact Handle strcpy((char*)pCurBlob, newNameStr.data()); pCurBlob += newNameStr.length()+1; // Nickname - *pCurBlob = '\0'; pCurBlob++; // First Name - *pCurBlob = '\0'; pCurBlob++; // Last Name - *pCurBlob = '\0'; pCurBlob++; // E-mail - *pCurBlob = '\0'; // Reason + *pCurBlob = '\0'; pCurBlob++; // First Name + *pCurBlob = '\0'; pCurBlob++; // Last Name + *pCurBlob = '\0'; pCurBlob++; // E-mail + *pCurBlob = '\0'; // Reason - CallService(MS_DB_EVENT_ADD, 0, (LPARAM) &dbei); - */ + CallService(MS_DB_EVENT_ADD, 0, (LPARAM) &dbei); + */ DBVARIANT dbv; if( !db_get_s(NULL, m_szModuleName, WHATSAPP_KEY_DEF_GROUP, &dbv, DBVT_WCHAR)) @@ -105,11 +105,11 @@ HANDLE WhatsAppProto::AddToContactList(const std::string& jid, BYTE type, bool d db_set_utf(hContact, m_szModuleName, WHATSAPP_KEY_PUSH_NAME, new_name); } - if (isChatRoom) - { - db_set_b(hContact, m_szModuleName, "SimpleChatRoom", 1); - //ForkThread(&WhatsAppProto::SendGetGroupInfoWorker, this, (void*) &jid); - } + if (isChatRoom) + { + db_set_b(hContact, m_szModuleName, "SimpleChatRoom", 1); + //ForkThread(&WhatsAppProto::SendGetGroupInfoWorker, this, (void*) &jid); + } return hContact; } else { @@ -117,27 +117,27 @@ HANDLE WhatsAppProto::AddToContactList(const std::string& jid, BYTE type, bool d } } - return INVALID_HANDLE_VALUE; + return INVALID_HANDLE_VALUE; } HANDLE WhatsAppProto::ContactIDToHContact(const std::string& phoneNumber) { - // Cache - std::map::iterator it = this->hContactByJid.find(phoneNumber); - if (it != this->hContactByJid.end()) - return it->second; + // Cache + std::map::iterator it = this->hContactByJid.find(phoneNumber); + if (it != this->hContactByJid.end()) + return it->second; - const char* idForContact = "ID"; - const char* idForChat = "ChatRoomID"; + const char* idForContact = "ID"; + const char* idForChat = "ChatRoomID"; for(HANDLE hContact = db_find_first(); - hContact; - hContact = db_find_next(hContact)) + hContact; + hContact = db_find_next(hContact)) { if(!IsMyContact(hContact, true)) continue; - const char* id = db_get_b(hContact, m_szModuleName, "ChatRoom", 0) > 0 ? idForChat : idForContact; + const char* id = db_get_b(hContact, m_szModuleName, "ChatRoom", 0) > 0 ? idForChat : idForContact; DBVARIANT dbv; if( !db_get_s(hContact,m_szModuleName, id,&dbv, DBVT_ASCIIZ)) @@ -145,7 +145,7 @@ HANDLE WhatsAppProto::ContactIDToHContact(const std::string& phoneNumber) if( strcmp(phoneNumber.c_str(),dbv.pszVal) == 0 ) { db_free(&dbv); - this->hContactByJid[phoneNumber] = hContact; + this->hContactByJid[phoneNumber] = hContact; return hContact; } @@ -159,8 +159,8 @@ HANDLE WhatsAppProto::ContactIDToHContact(const std::string& phoneNumber) void WhatsAppProto::SetAllContactStatuses(int status, bool reset_client) { for (HANDLE hContact = db_find_first(); - hContact; - hContact = db_find_next(hContact)) + hContact; + hContact = db_find_next(hContact)) { if (!IsMyContact(hContact)) continue; @@ -173,7 +173,7 @@ void WhatsAppProto::SetAllContactStatuses(int status, bool reset_client) db_free(&dbv); } - db_set_ws(hContact, "CList", "StatusMsg", _T("")); + db_set_ws(hContact, "CList", "StatusMsg", _T("")); } if (db_get_w(hContact,m_szModuleName,"Status",ID_STATUS_OFFLINE) != status) @@ -183,87 +183,87 @@ void WhatsAppProto::SetAllContactStatuses(int status, bool reset_client) void WhatsAppProto::ProcessBuddyList(void*) { - std::vector jids; - DBVARIANT dbv; - for (HANDLE hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { - if (!IsMyContact(hContact)) - continue; - - if (!db_get_s(hContact, m_szModuleName, WHATSAPP_KEY_ID, &dbv, DBVT_ASCIIZ)) { - std::string id(dbv.pszVal); - db_free(&dbv); - - CODE_BLOCK_TRY - if (!db_get_b(hContact, "CList", "Hidden", 0)) - { - // Do not request picture for inactive groups - this would make the group visible again - jids.push_back(id); - } - if (db_get_b(hContact, m_szModuleName, "SimpleChatRoom", 0) == 0) - { - this->connection->sendQueryLastOnline(id); - this->connection->sendPresenceSubscriptionRequest(id); - } - CODE_BLOCK_CATCH_ALL - } - } - if (jids.size() > 0) { - CODE_BLOCK_TRY - this->connection->sendGetPictureIds(jids); - CODE_BLOCK_CATCH_ALL - } - CODE_BLOCK_TRY - this->connection->sendGetGroups(); - this->connection->sendGetOwningGroups(); - CODE_BLOCK_CATCH_ALL + std::vector jids; + DBVARIANT dbv; + for (HANDLE hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) { + if (!IsMyContact(hContact)) + continue; + + if (!db_get_s(hContact, m_szModuleName, WHATSAPP_KEY_ID, &dbv, DBVT_ASCIIZ)) { + std::string id(dbv.pszVal); + db_free(&dbv); + + CODE_BLOCK_TRY + if (!db_get_b(hContact, "CList", "Hidden", 0)) + { + // Do not request picture for inactive groups - this would make the group visible again + jids.push_back(id); + } + if (db_get_b(hContact, m_szModuleName, "SimpleChatRoom", 0) == 0) + { + this->connection->sendQueryLastOnline(id); + this->connection->sendPresenceSubscriptionRequest(id); + } + CODE_BLOCK_CATCH_ALL + } + } + if (jids.size() > 0) { + CODE_BLOCK_TRY + this->connection->sendGetPictureIds(jids); + CODE_BLOCK_CATCH_ALL + } + CODE_BLOCK_TRY + this->connection->sendGetGroups(); + this->connection->sendGetOwningGroups(); + CODE_BLOCK_CATCH_ALL } void WhatsAppProto::SearchAckThread(void *targ) { char *id = mir_utf8encodeT((TCHAR*)targ); - std::string jid(id); - jid.append("@s.whatsapp.net"); + std::string jid(id); + jid.append("@s.whatsapp.net"); - this->connection->sendQueryLastOnline(jid); - this->connection->sendPresenceSubscriptionRequest(jid); + this->connection->sendQueryLastOnline(jid); + this->connection->sendPresenceSubscriptionRequest(jid); - mir_free(targ); - mir_free(id); + mir_free(targ); + mir_free(id); } void WhatsAppProto::onAvailable(const std::string& paramString, bool paramBoolean) { - HANDLE hContact = this->AddToContactList(paramString, 0, false); - if (hContact != NULL) - { - if (paramBoolean) - { - /* - this->connection->sendGetPicture(paramString, "image", "old", "new"); - std::vector ids; - ids.push_back(paramString); - this->connection->sendGetPictureIds(ids); - */ - db_set_w(hContact, m_szModuleName, "Status", ID_STATUS_ONLINE); - } - else - { - db_set_w(hContact, m_szModuleName, "Status", ID_STATUS_OFFLINE); - this->UpdateStatusMsg(hContact); - } - } - - db_set_dw(hContact, this->m_szModuleName, WHATSAPP_KEY_LAST_SEEN, 0); - this->UpdateStatusMsg(hContact); + HANDLE hContact = this->AddToContactList(paramString, 0, false); + if (hContact != NULL) + { + if (paramBoolean) + { + /* + this->connection->sendGetPicture(paramString, "image", "old", "new"); + std::vector ids; + ids.push_back(paramString); + this->connection->sendGetPictureIds(ids); + */ + db_set_w(hContact, m_szModuleName, "Status", ID_STATUS_ONLINE); + } + else + { + db_set_w(hContact, m_szModuleName, "Status", ID_STATUS_OFFLINE); + this->UpdateStatusMsg(hContact); + } + } + + db_set_dw(hContact, this->m_szModuleName, WHATSAPP_KEY_LAST_SEEN, 0); + this->UpdateStatusMsg(hContact); } void WhatsAppProto::onLastSeen(const std::string& paramString1, int paramInt, std::string* paramString2) { - /* - HANDLE hContact = this->ContactIDToHContact(paramString1); - if (hContact == NULL) - { - // This contact was searched + /* + HANDLE hContact = this->ContactIDToHContact(paramString1); + if (hContact == NULL) + { + // This contact was searched PROTOSEARCHRESULT isr = {0}; isr.cbSize = sizeof(isr); isr.flags = PSR_TCHAR; @@ -272,478 +272,478 @@ void WhatsAppProto::onLastSeen(const std::string& paramString1, int paramInt, st isr.firstName = ""; isr.lastName = ""; isr.email = ""; - ProtoBroadcastAck(m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, targ, (LPARAM)&isr); - // #TODO - } - */ - HANDLE hContact = this->AddToContactList(paramString1, 0, false); - db_set_dw(hContact, this->m_szModuleName, WHATSAPP_KEY_LAST_SEEN, paramInt); + ProtoBroadcastAck(m_szModuleName, NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, targ, (LPARAM)&isr); + // #TODO + } + */ + HANDLE hContact = this->AddToContactList(paramString1, 0, false); + db_set_dw(hContact, this->m_szModuleName, WHATSAPP_KEY_LAST_SEEN, paramInt); - this->UpdateStatusMsg(hContact); + this->UpdateStatusMsg(hContact); } void WhatsAppProto::UpdateStatusMsg(HANDLE hContact) { - std::wstringstream ss; + std::wstringstream ss; - int lastSeen = db_get_dw(hContact, m_szModuleName, WHATSAPP_KEY_LAST_SEEN, -1); - if (lastSeen != -1) - { - time_t timestamp = time(NULL) - lastSeen; - - tm* t = localtime(×tamp); - ss << _T("Last seen on ") << std::setfill(_T('0')) << std::setw(2) << (t->tm_mon + 1) << - _T("/") << std::setw(2) << t->tm_mday << _T("/") << (t->tm_year + 1900) << _T(" ") - << std::setw(2) << t->tm_hour << _T(":") << std::setw(2) << t->tm_min; - } + int lastSeen = db_get_dw(hContact, m_szModuleName, WHATSAPP_KEY_LAST_SEEN, -1); + if (lastSeen != -1) + { + time_t timestamp = time(NULL) - lastSeen; + + tm* t = localtime(×tamp); + ss << _T("Last seen on ") << std::setfill(_T('0')) << std::setw(2) << (t->tm_mon + 1) << + _T("/") << std::setw(2) << t->tm_mday << _T("/") << (t->tm_year + 1900) << _T(" ") + << std::setw(2) << t->tm_hour << _T(":") << std::setw(2) << t->tm_min; + } - int state = db_get_dw(hContact, m_szModuleName, WHATSAPP_KEY_LAST_MSG_STATE, 2); - if (state < 2 && lastSeen != -1) - ss << _T(" - "); - for (; state < 2; ++state) - ss << _T("\u2713"); + int state = db_get_dw(hContact, m_szModuleName, WHATSAPP_KEY_LAST_MSG_STATE, 2); + if (state < 2 && lastSeen != -1) + ss << _T(" - "); + for (; state < 2; ++state) + ss << _T("\u2713"); - db_set_ws(hContact, "CList", "StatusMsg", ss.str().c_str()); + db_set_ws(hContact, "CList", "StatusMsg", ss.str().c_str()); } void WhatsAppProto::onPictureChanged(const std::string& from, const std::string& author, bool set) { - if (this->isOnline()) - { - vector ids; - ids.push_back(from); - this->connection->sendGetPictureIds(ids); - } + if (this->isOnline()) + { + vector ids; + ids.push_back(from); + this->connection->sendGetPictureIds(ids); + } } void WhatsAppProto::onSendGetPicture(const std::string& jid, const std::vector& data, const std::string& oldId, const std::string& newId) { - HANDLE hContact = this->ContactIDToHContact(jid); - if (hContact) - { - LOG("Updating avatar for jid %s", jid.c_str()); - - // Save avatar - std::tstring filename = this->GetAvatarFolder() ; - if (_taccess(filename.c_str(), 0)) - CallService(MS_UTILS_CREATEDIRTREET, 0, (LPARAM)filename.c_str()); - filename = filename + _T("\\") + (TCHAR*) _A2T(jid.c_str()) + _T("-") + (TCHAR*) _A2T(newId.c_str()) +_T(".jpg"); - FILE *f = _tfopen(filename.c_str(), _T("wb")); - int r = (int)fwrite(std::string(data.begin(), data.end()).c_str(), 1, data.size(), f); - fclose(f); - - PROTO_AVATAR_INFORMATIONT ai = {sizeof(ai)}; - ai.hContact = hContact; - ai.format = PA_FORMAT_JPEG; - _tcsncpy(ai.filename, filename.c_str(), SIZEOF(ai.filename)); - ai.filename[SIZEOF(ai.filename)-1] = 0; - - int ackResult; - if (r > 0) - { - db_set_s(hContact, m_szModuleName, WHATSAPP_KEY_AVATAR_ID, newId.c_str()); - ackResult = ACKRESULT_SUCCESS; - } - else - { - ackResult = ACKRESULT_FAILED; - } - ProtoBroadcastAck(m_szModuleName, ai.hContact, ACKTYPE_AVATAR, ackResult, (HANDLE)&ai, 0); - } + HANDLE hContact = this->ContactIDToHContact(jid); + if (hContact) + { + LOG("Updating avatar for jid %s", jid.c_str()); + + // Save avatar + std::tstring filename = this->GetAvatarFolder() ; + if (_taccess(filename.c_str(), 0)) + CallService(MS_UTILS_CREATEDIRTREET, 0, (LPARAM)filename.c_str()); + filename = filename + _T("\\") + (TCHAR*) _A2T(jid.c_str()) + _T("-") + (TCHAR*) _A2T(newId.c_str()) +_T(".jpg"); + FILE *f = _tfopen(filename.c_str(), _T("wb")); + int r = (int)fwrite(std::string(data.begin(), data.end()).c_str(), 1, data.size(), f); + fclose(f); + + PROTO_AVATAR_INFORMATIONT ai = {sizeof(ai)}; + ai.hContact = hContact; + ai.format = PA_FORMAT_JPEG; + _tcsncpy(ai.filename, filename.c_str(), SIZEOF(ai.filename)); + ai.filename[SIZEOF(ai.filename)-1] = 0; + + int ackResult; + if (r > 0) + { + db_set_s(hContact, m_szModuleName, WHATSAPP_KEY_AVATAR_ID, newId.c_str()); + ackResult = ACKRESULT_SUCCESS; + } + else + { + ackResult = ACKRESULT_FAILED; + } + ProtoBroadcastAck(m_szModuleName, ai.hContact, ACKTYPE_AVATAR, ackResult, (HANDLE)&ai, 0); + } } void WhatsAppProto::onSendGetPictureIds(std::map* ids) { - for (std::map::iterator it = ids->begin(); it != ids->end(); ++it) - { - HANDLE hContact = this->AddToContactList(it->first); - if (hContact != NULL) - { - DBVARIANT dbv; - std::string oldId; - if (db_get_s(hContact, m_szModuleName, WHATSAPP_KEY_AVATAR_ID, &dbv, DBVT_ASCIIZ)) - { - oldId = ""; - } - else - { - oldId = dbv.pszVal; - db_free(&dbv); - } - - if (it->second.size() > 0 && it->second.compare(oldId) != 0) - { - CODE_BLOCK_TRY - this->connection->sendGetPicture(it->first, "image", oldId, it->second); - CODE_BLOCK_CATCH_ALL - } - } - } + for (std::map::iterator it = ids->begin(); it != ids->end(); ++it) + { + HANDLE hContact = this->AddToContactList(it->first); + if (hContact != NULL) + { + DBVARIANT dbv; + std::string oldId; + if (db_get_s(hContact, m_szModuleName, WHATSAPP_KEY_AVATAR_ID, &dbv, DBVT_ASCIIZ)) + { + oldId = ""; + } + else + { + oldId = dbv.pszVal; + db_free(&dbv); + } + + if (it->second.size() > 0 && it->second.compare(oldId) != 0) + { + CODE_BLOCK_TRY + this->connection->sendGetPicture(it->first, "image", oldId, it->second); + CODE_BLOCK_CATCH_ALL + } + } + } } string WhatsAppProto::GetContactDisplayName(HANDLE hContact) { - return string((CHAR*) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, 0)); + return string((CHAR*) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, 0)); } string WhatsAppProto::GetContactDisplayName(const string& jid) { - HANDLE hContact = this->ContactIDToHContact(jid); - return hContact ? this->GetContactDisplayName(hContact) : (string("+")+ Utilities::removeWaDomainFromJid(jid)); + HANDLE hContact = this->ContactIDToHContact(jid); + return hContact ? this->GetContactDisplayName(hContact) : (string("+")+ Utilities::removeWaDomainFromJid(jid)); } // Group contacts -------------------------- void WhatsAppProto::SendGetGroupInfoWorker(void* data) { - if (this->isOnline()) - { - this->connection->sendGetGroupInfo(*((std::string*) data)); - } + if (this->isOnline()) + { + this->connection->sendGetGroupInfo(*((std::string*) data)); + } } void WhatsAppProto::onGroupInfo(const std::string& gjid, const std::string& ownerJid, const std::string& subject, const std::string& createrJid, int paramInt1, int paramInt2) { - LOG("'%s', '%s', '%s', '%s'", gjid.c_str(), ownerJid.c_str(), subject.c_str(), createrJid.c_str()); - HANDLE hContact = ContactIDToHContact(gjid); - if (!hContact) - { - LOG("Group info requested for non existing contact '%s'", gjid.c_str()); - return; - } - db_set_b(hContact, m_szModuleName, "SimpleChatRoom", ownerJid.compare(this->jid) == 0 ? 2 : 1); - if (this->isOnline()) - { - this->connection->sendGetParticipants(gjid); - } + LOG("'%s', '%s', '%s', '%s'", gjid.c_str(), ownerJid.c_str(), subject.c_str(), createrJid.c_str()); + HANDLE hContact = ContactIDToHContact(gjid); + if (!hContact) + { + LOG("Group info requested for non existing contact '%s'", gjid.c_str()); + return; + } + db_set_b(hContact, m_szModuleName, "SimpleChatRoom", ownerJid.compare(this->jid) == 0 ? 2 : 1); + if (this->isOnline()) + { + this->connection->sendGetParticipants(gjid); + } } void WhatsAppProto::onGroupInfoFromList(const std::string& paramString1, const std::string& paramString2, const std::string& paramString3, const std::string& paramString4, int paramInt1, int paramInt2) { - // Called before onOwningGroups() or onParticipatingGroups() is called! - LOG(""); + // Called before onOwningGroups() or onParticipatingGroups() is called! + LOG(""); } void WhatsAppProto::onGroupNewSubject(const std::string& from, const std::string& author, const std::string& newSubject, int paramInt) { - LOG("'%s', '%s', '%s'", from.c_str(), author.c_str(), newSubject.c_str()); - HANDLE hContact = this->AddToContactList(from, 0, false, newSubject.c_str(), true); + LOG("'%s', '%s', '%s'", from.c_str(), author.c_str(), newSubject.c_str()); + HANDLE hContact = this->AddToContactList(from, 0, false, newSubject.c_str(), true); } void WhatsAppProto::onGroupAddUser(const std::string& paramString1, const std::string& paramString2) { - LOG("%s - user: %s", paramString1.c_str(), paramString2.c_str()); - HANDLE hContact = this->AddToContactList(paramString1); - std::string groupName(this->GetContactDisplayName(hContact)); + LOG("%s - user: %s", paramString1.c_str(), paramString2.c_str()); + HANDLE hContact = this->AddToContactList(paramString1); + std::string groupName(this->GetContactDisplayName(hContact)); - if (paramString2.compare(this->jid) == 0) - { - this->NotifyEvent(groupName, this->TranslateStr("You have been added to the group"), hContact, WHATSAPP_EVENT_OTHER); - db_set_b(hContact, m_szModuleName, "IsGroupMember", 1); - } - else - { - this->NotifyEvent(groupName, this->TranslateStr("User '%s' has been added to the group", - this->GetContactDisplayName(paramString2).c_str()), hContact, WHATSAPP_EVENT_OTHER); - } + if (paramString2.compare(this->jid) == 0) + { + this->NotifyEvent(groupName, this->TranslateStr("You have been added to the group"), hContact, WHATSAPP_EVENT_OTHER); + db_set_b(hContact, m_szModuleName, "IsGroupMember", 1); + } + else + { + this->NotifyEvent(groupName, this->TranslateStr("User '%s' has been added to the group", + this->GetContactDisplayName(paramString2).c_str()), hContact, WHATSAPP_EVENT_OTHER); + } - if(this->isOnline()) - { - this->connection->sendGetGroupInfo(paramString1); - } + if(this->isOnline()) + { + this->connection->sendGetGroupInfo(paramString1); + } } void WhatsAppProto::onGroupRemoveUser(const std::string& paramString1, const std::string& paramString2) { - LOG("%s - user: %s", paramString1.c_str(), paramString2.c_str()); - HANDLE hContact = this->ContactIDToHContact(paramString1); - if (!hContact) - return; - - string groupName(this->GetContactDisplayName(hContact)); - - if (paramString2.compare(this->jid) == 0) - { - //db_set_b(hContact, "CList", "Hidden", 1); - db_set_b(hContact, m_szModuleName, "IsGroupMember", 0); - - this->NotifyEvent(groupName, this->TranslateStr("You have been removed from the group"), - hContact, WHATSAPP_EVENT_OTHER); - } - else if(this->isOnline()) - { - this->NotifyEvent(groupName, this->TranslateStr("User '%s' has been removed from the group", - this->GetContactDisplayName(paramString2).c_str()), hContact, WHATSAPP_EVENT_OTHER); - this->connection->sendGetGroupInfo(paramString1); - //this->connection->sendGetParticipants(paramString1); - } + LOG("%s - user: %s", paramString1.c_str(), paramString2.c_str()); + HANDLE hContact = this->ContactIDToHContact(paramString1); + if (!hContact) + return; + + string groupName(this->GetContactDisplayName(hContact)); + + if (paramString2.compare(this->jid) == 0) + { + //db_set_b(hContact, "CList", "Hidden", 1); + db_set_b(hContact, m_szModuleName, "IsGroupMember", 0); + + this->NotifyEvent(groupName, this->TranslateStr("You have been removed from the group"), + hContact, WHATSAPP_EVENT_OTHER); + } + else if(this->isOnline()) + { + this->NotifyEvent(groupName, this->TranslateStr("User '%s' has been removed from the group", + this->GetContactDisplayName(paramString2).c_str()), hContact, WHATSAPP_EVENT_OTHER); + this->connection->sendGetGroupInfo(paramString1); + //this->connection->sendGetParticipants(paramString1); + } } void WhatsAppProto::onLeaveGroup(const std::string& paramString) { - // Won't be called for unknown reasons! - LOG("%s", this->GetContactDisplayName(paramString).c_str()); - HANDLE hContact = this->ContactIDToHContact(paramString); - if (hContact) - { - //db_set_b(hContact, "CList", "Hidden", 1); - db_set_b(hContact, m_szModuleName, "IsGroupMember", 0); - } + // Won't be called for unknown reasons! + LOG("%s", this->GetContactDisplayName(paramString).c_str()); + HANDLE hContact = this->ContactIDToHContact(paramString); + if (hContact) + { + //db_set_b(hContact, "CList", "Hidden", 1); + db_set_b(hContact, m_szModuleName, "IsGroupMember", 0); + } } void WhatsAppProto::onGetParticipants(const std::string& gjid, const std::vector& participants) { - LOG("%s", this->GetContactDisplayName(gjid).c_str()); - - HANDLE hUserContact; - HANDLE hContact = this->ContactIDToHContact(gjid); - if (!hContact) - return; - - if (db_get_b(hContact, "CList", "Hidden", 0) == 1) - return; - - bool isHidden = true; - bool isOwningGroup = db_get_b(hContact, m_szModuleName, "SimpleChatRoom", 0) == 2; - - if (isOwningGroup) - { - this->isMemberByGroupContact[hContact].clear(); - } - - for (std::vector::const_iterator it = participants.begin(); it != participants.end(); ++it) - { - // Hide, if we are not member of the group - // Sometimes the group is shown shortly after hiding it again, due to other threads which stored the contact - // in a cache before it has been removed (E.g. picture-id list in processBuddyList) - if (isHidden && this->jid.compare(*it) == 0) - { - isHidden = false; - if (!isOwningGroup) - { - // Break, as we don't need to collect group-members - break; - } - } - - // #TODO Slow for big count of participants - // #TODO If a group is hidden it has been deleted from the local contact list - // => don't allow to add users anymore - if (isOwningGroup) - { - hUserContact = this->ContactIDToHContact(*it); - if (hUserContact) - { - this->isMemberByGroupContact[hContact][hUserContact] = true; - } - } - } - if (isHidden) - { - //db_set_b(hContact, "CList", "Hidden", 1); - // #TODO Check if it's possible to reach this point at all - db_set_b(hContact, m_szModuleName, "IsGroupMember", 0); - } + LOG("%s", this->GetContactDisplayName(gjid).c_str()); + + HANDLE hUserContact; + HANDLE hContact = this->ContactIDToHContact(gjid); + if (!hContact) + return; + + if (db_get_b(hContact, "CList", "Hidden", 0) == 1) + return; + + bool isHidden = true; + bool isOwningGroup = db_get_b(hContact, m_szModuleName, "SimpleChatRoom", 0) == 2; + + if (isOwningGroup) + { + this->isMemberByGroupContact[hContact].clear(); + } + + for (std::vector::const_iterator it = participants.begin(); it != participants.end(); ++it) + { + // Hide, if we are not member of the group + // Sometimes the group is shown shortly after hiding it again, due to other threads which stored the contact + // in a cache before it has been removed (E.g. picture-id list in processBuddyList) + if (isHidden && this->jid.compare(*it) == 0) + { + isHidden = false; + if (!isOwningGroup) + { + // Break, as we don't need to collect group-members + break; + } + } + + // #TODO Slow for big count of participants + // #TODO If a group is hidden it has been deleted from the local contact list + // => don't allow to add users anymore + if (isOwningGroup) + { + hUserContact = this->ContactIDToHContact(*it); + if (hUserContact) + { + this->isMemberByGroupContact[hContact][hUserContact] = true; + } + } + } + if (isHidden) + { + //db_set_b(hContact, "CList", "Hidden", 1); + // #TODO Check if it's possible to reach this point at all + db_set_b(hContact, m_szModuleName, "IsGroupMember", 0); + } } // Menu handler INT_PTR __cdecl WhatsAppProto::OnAddContactToGroup(WPARAM wParam, LPARAM, LPARAM lParam) { - string a = GetContactDisplayName((HANDLE) wParam); - string b = GetContactDisplayName((HANDLE) lParam); - LOG("Request add user %s to group %s", a.c_str(), b.c_str()); + string a = GetContactDisplayName((HANDLE) wParam); + string b = GetContactDisplayName((HANDLE) lParam); + LOG("Request add user %s to group %s", a.c_str(), b.c_str()); - if (!this->isOnline()) - return NULL; + if (!this->isOnline()) + return NULL; - DBVARIANT dbv; + DBVARIANT dbv; - if (db_get_s((HANDLE) wParam, m_szModuleName, "ID", &dbv, DBVT_ASCIIZ)) - return NULL; + if (db_get_s((HANDLE) wParam, m_szModuleName, "ID", &dbv, DBVT_ASCIIZ)) + return NULL; - std::vector participants; - participants.push_back(string(dbv.pszVal)); - db_free(&dbv); + std::vector participants; + participants.push_back(string(dbv.pszVal)); + db_free(&dbv); - if (db_get_s((HANDLE) lParam, m_szModuleName, "ID", &dbv, DBVT_ASCIIZ)) - return NULL; + if (db_get_s((HANDLE) lParam, m_szModuleName, "ID", &dbv, DBVT_ASCIIZ)) + return NULL; - this->connection->sendAddParticipants(string(dbv.pszVal), participants); + this->connection->sendAddParticipants(string(dbv.pszVal), participants); - db_free(&dbv); - return NULL; + db_free(&dbv); + return NULL; } // Menu handler INT_PTR __cdecl WhatsAppProto::OnRemoveContactFromGroup(WPARAM wParam, LPARAM, LPARAM lParam) { - string a = GetContactDisplayName((HANDLE) wParam); - string b = GetContactDisplayName((HANDLE) lParam); - LOG("Request remove user %s from group %s", a.c_str(), b.c_str()); + string a = GetContactDisplayName((HANDLE) wParam); + string b = GetContactDisplayName((HANDLE) lParam); + LOG("Request remove user %s from group %s", a.c_str(), b.c_str()); - if (!this->isOnline()) - return NULL; + if (!this->isOnline()) + return NULL; - DBVARIANT dbv; + DBVARIANT dbv; - if (db_get_s((HANDLE) lParam, m_szModuleName, "ID", &dbv, DBVT_ASCIIZ)) - return NULL; + if (db_get_s((HANDLE) lParam, m_szModuleName, "ID", &dbv, DBVT_ASCIIZ)) + return NULL; - std::vector participants; - participants.push_back(string(dbv.pszVal)); - db_free(&dbv); + std::vector participants; + participants.push_back(string(dbv.pszVal)); + db_free(&dbv); - if (db_get_s((HANDLE) wParam, m_szModuleName, "ID", &dbv, DBVT_ASCIIZ)) - return NULL; + if (db_get_s((HANDLE) wParam, m_szModuleName, "ID", &dbv, DBVT_ASCIIZ)) + return NULL; - this->connection->sendRemoveParticipants(string(dbv.pszVal), participants); + this->connection->sendRemoveParticipants(string(dbv.pszVal), participants); - db_free(&dbv); - return NULL; + db_free(&dbv); + return NULL; } void WhatsAppProto::onOwningGroups(const std::vector& paramVector) { - LOG(""); - this->HandleReceiveGroups(paramVector, true); + LOG(""); + this->HandleReceiveGroups(paramVector, true); } void WhatsAppProto::onParticipatingGroups(const std::vector& paramVector) { - LOG(""); - this->HandleReceiveGroups(paramVector, false); + LOG(""); + this->HandleReceiveGroups(paramVector, false); } void WhatsAppProto::HandleReceiveGroups(const std::vector& groups, bool isOwned) { - HANDLE hContact; - map isMember; // at the moment, only members of owning groups are stored - - // This could take long time if there are many new groups which aren't - // yet stored to the database. But that should be a rare case - for (std::vector::const_iterator it = groups.begin(); it != groups.end(); ++it) - { - hContact = this->AddToContactList(*it, 0, false, NULL, true); - db_set_b(hContact, m_szModuleName, "IsGroupMember", 1); - if (isOwned) - { - this->isMemberByGroupContact[hContact]; // []-operator creates entry, if it doesn't exist - db_set_b(hContact, m_szModuleName, "SimpleChatRoom", 2); - this->connection->sendGetParticipants(*it); - } - else - { - isMember[hContact] = true; - } - } - - // Mark as non-meber if group only exists locally - if (!isOwned) - { - for (hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) - { - if (IsMyContact(hContact) && db_get_b(hContact, m_szModuleName, "SimpleChatRoom", 0) > 0) - { - //LOG("Set IsGroupMember to 0 for '%s'", this->GetContactDisplayName(hContact).c_str()); - db_set_b(hContact, m_szModuleName, "IsGroupMember", - isMember.find(hContact) == isMember.end() ? 0 : 1); - } - } - } + HANDLE hContact; + map isMember; // at the moment, only members of owning groups are stored + + // This could take long time if there are many new groups which aren't + // yet stored to the database. But that should be a rare case + for (std::vector::const_iterator it = groups.begin(); it != groups.end(); ++it) + { + hContact = this->AddToContactList(*it, 0, false, NULL, true); + db_set_b(hContact, m_szModuleName, "IsGroupMember", 1); + if (isOwned) + { + this->isMemberByGroupContact[hContact]; // []-operator creates entry, if it doesn't exist + db_set_b(hContact, m_szModuleName, "SimpleChatRoom", 2); + this->connection->sendGetParticipants(*it); + } + else + { + isMember[hContact] = true; + } + } + + // Mark as non-meber if group only exists locally + if (!isOwned) + { + for (hContact = db_find_first(); hContact; hContact = db_find_next(hContact)) + { + if (IsMyContact(hContact) && db_get_b(hContact, m_szModuleName, "SimpleChatRoom", 0) > 0) + { + //LOG("Set IsGroupMember to 0 for '%s'", this->GetContactDisplayName(hContact).c_str()); + db_set_b(hContact, m_szModuleName, "IsGroupMember", + isMember.find(hContact) == isMember.end() ? 0 : 1); + } + } + } } void WhatsAppProto::onGroupCreated(const std::string& paramString1, const std::string& paramString2) { - // Must be received after onOwningGroups() :/ - LOG("%s / %s", paramString1.c_str(), paramString2.c_str()); - string jid = paramString2 +string("@")+ paramString1; - HANDLE hContact = this->AddToContactList(jid, 0, false, NULL, true); - db_set_b(hContact, m_szModuleName, "SimpleChatRoom", 2); + // Must be received after onOwningGroups() :/ + LOG("%s / %s", paramString1.c_str(), paramString2.c_str()); + string jid = paramString2 +string("@")+ paramString1; + HANDLE hContact = this->AddToContactList(jid, 0, false, NULL, true); + db_set_b(hContact, m_szModuleName, "SimpleChatRoom", 2); } // Menu-handler int __cdecl WhatsAppProto::OnCreateGroup(WPARAM wParam, LPARAM lParam) { - LOG(""); - input_box* ib = new input_box; - ib->defaultValue = _T(""); - ib->limit = WHATSAPP_GROUP_NAME_LIMIT; - ib->proto = this; - ib->text = _T("Enter group subject"); - ib->title = _T("WhatsApp - Create Group"); - ib->thread = &WhatsAppProto::SendCreateGroupWorker; - HWND hDlg = CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_INPUTBOX), 0, WhatsAppInputBoxProc, - reinterpret_cast(ib)); - ShowWindow(hDlg, SW_SHOW); - return FALSE; + LOG(""); + input_box* ib = new input_box; + ib->defaultValue = _T(""); + ib->limit = WHATSAPP_GROUP_NAME_LIMIT; + ib->proto = this; + ib->text = _T("Enter group subject"); + ib->title = _T("WhatsApp - Create Group"); + ib->thread = &WhatsAppProto::SendCreateGroupWorker; + HWND hDlg = CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_INPUTBOX), 0, WhatsAppInputBoxProc, + reinterpret_cast(ib)); + ShowWindow(hDlg, SW_SHOW); + return FALSE; } void __cdecl WhatsAppProto::SendSetGroupNameWorker(void* data) { - input_box_ret* ibr(static_cast(data)); - string groupName(ibr->value); - mir_free(ibr->value); - DBVARIANT dbv; - if (!db_get_s(*((HANDLE*) ibr->userData), m_szModuleName, WHATSAPP_KEY_ID, &dbv, DBVT_ASCIIZ) - && this->isOnline()) - { - this->connection->sendSetNewSubject(dbv.pszVal, groupName); - db_free(&dbv); - } - delete ibr->userData; - delete ibr; + input_box_ret* ibr(static_cast(data)); + string groupName(ibr->value); + mir_free(ibr->value); + DBVARIANT dbv; + if (!db_get_s(*((HANDLE*) ibr->userData), m_szModuleName, WHATSAPP_KEY_ID, &dbv, DBVT_ASCIIZ) + && this->isOnline()) + { + this->connection->sendSetNewSubject(dbv.pszVal, groupName); + db_free(&dbv); + } + delete ibr->userData; + delete ibr; } void __cdecl WhatsAppProto::SendCreateGroupWorker(void* data) { - input_box_ret* ibr(static_cast(data)); - string groupName(ibr->value); - mir_free(ibr->value); - if (this->isOnline()) - { - this->connection->sendCreateGroupChat(groupName); - } + input_box_ret* ibr(static_cast(data)); + string groupName(ibr->value); + mir_free(ibr->value); + if (this->isOnline()) + { + this->connection->sendCreateGroupChat(groupName); + } } int __cdecl WhatsAppProto::OnChangeGroupSubject(WPARAM wParam, LPARAM lParam) { - DBVARIANT dbv; - HANDLE hContact = reinterpret_cast(wParam); - input_box* ib = new input_box; - - if (db_get_s(hContact, m_szModuleName, WHATSAPP_KEY_PUSH_NAME, &dbv, DBVT_WCHAR)) - { - ib->defaultValue = _T(""); - } - else - { - ib->defaultValue = dbv.ptszVal; - db_free(&dbv); - } - ib->limit = WHATSAPP_GROUP_NAME_LIMIT; - ib->text = _T("Enter new group subject"); - ib->title = _T("WhatsApp - Change Group Subject"); - - ib->thread = &WhatsAppProto::SendSetGroupNameWorker; - ib->proto = this; - HANDLE* hContactPtr = new HANDLE(hContact); - ib->userData = (void*) hContactPtr; - - HWND hDlg = CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_INPUTBOX), 0, WhatsAppInputBoxProc, - reinterpret_cast(ib)); - ShowWindow(hDlg, SW_SHOW); - return 0; + DBVARIANT dbv; + HANDLE hContact = reinterpret_cast(wParam); + input_box* ib = new input_box; + + if (db_get_s(hContact, m_szModuleName, WHATSAPP_KEY_PUSH_NAME, &dbv, DBVT_WCHAR)) + { + ib->defaultValue = _T(""); + } + else + { + ib->defaultValue = dbv.ptszVal; + db_free(&dbv); + } + ib->limit = WHATSAPP_GROUP_NAME_LIMIT; + ib->text = _T("Enter new group subject"); + ib->title = _T("WhatsApp - Change Group Subject"); + + ib->thread = &WhatsAppProto::SendSetGroupNameWorker; + ib->proto = this; + HANDLE* hContactPtr = new HANDLE(hContact); + ib->userData = (void*) hContactPtr; + + HWND hDlg = CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_INPUTBOX), 0, WhatsAppInputBoxProc, + reinterpret_cast(ib)); + ShowWindow(hDlg, SW_SHOW); + return 0; } int __cdecl WhatsAppProto::OnLeaveGroup(WPARAM wParam, LPARAM) { - DBVARIANT dbv; - HANDLE hContact = reinterpret_cast(wParam); - if (this->isOnline() && !db_get_s(hContact, m_szModuleName, WHATSAPP_KEY_ID, &dbv, DBVT_ASCIIZ)) - { - db_set_b(hContact, m_szModuleName, "IsGroupMember", 0); - this->connection->sendLeaveGroup(dbv.pszVal); - db_free(&dbv); - } - return 0; + DBVARIANT dbv; + HANDLE hContact = reinterpret_cast(wParam); + if (this->isOnline() && !db_get_s(hContact, m_szModuleName, WHATSAPP_KEY_ID, &dbv, DBVT_ASCIIZ)) + { + db_set_b(hContact, m_szModuleName, "IsGroupMember", 0); + this->connection->sendLeaveGroup(dbv.pszVal); + db_free(&dbv); + } + return 0; } \ No newline at end of file diff --git a/protocols/WhatsApp/src/dialogs.cpp b/protocols/WhatsApp/src/dialogs.cpp index e26086910a..bcfd295bcd 100644 --- a/protocols/WhatsApp/src/dialogs.cpp +++ b/protocols/WhatsApp/src/dialogs.cpp @@ -2,8 +2,8 @@ INT_PTR CALLBACK WhatsAppAccountProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) { - WhatsAppProto *proto; - + WhatsAppProto *proto; + switch ( message ) { @@ -20,7 +20,7 @@ INT_PTR CALLBACK WhatsAppAccountProc( HWND hwnd, UINT message, WPARAM wparam, LP SetDlgItemTextA(hwnd,IDC_CC,dbv.pszVal); db_free(&dbv); } - + if ( !db_get_s(0,proto->ModuleName(),WHATSAPP_KEY_LOGIN,&dbv,DBVT_ASCIIZ)) { SetDlgItemTextA(hwnd,IDC_LOGIN,dbv.pszVal); @@ -40,68 +40,67 @@ INT_PTR CALLBACK WhatsAppAccountProc( HWND hwnd, UINT message, WPARAM wparam, LP SetDlgItemTextA(hwnd,IDC_PW,dbv.pszVal); db_free(&dbv); } - if (!proto->isOffline()) { - SendMessage(GetDlgItem(hwnd,IDC_CC),EM_SETREADONLY,1,0); + SendMessage(GetDlgItem(hwnd,IDC_CC),EM_SETREADONLY,1,0); SendMessage(GetDlgItem(hwnd,IDC_LOGIN),EM_SETREADONLY,1,0); SendMessage(GetDlgItem(hwnd,IDC_NICK),EM_SETREADONLY,1,0); - SendMessage(GetDlgItem(hwnd,IDC_PW),EM_SETREADONLY,1,0); - } + SendMessage(GetDlgItem(hwnd,IDC_PW),EM_SETREADONLY,1,0); + } return TRUE; case WM_COMMAND: - if (LOWORD(wparam) == IDC_BUTTON_REQUEST_CODE || LOWORD(wparam) == IDC_BUTTON_REGISTER) - { - proto = reinterpret_cast(GetWindowLongPtr(hwnd,GWLP_USERDATA)); - - char cc[5]; - GetDlgItemTextA(hwnd, IDC_CC, cc, sizeof(cc)); - char number[128]; - GetDlgItemTextA(hwnd, IDC_LOGIN, number, sizeof(number)); - - if (LOWORD(wparam) == IDC_BUTTON_REQUEST_CODE) - { - if (MessageBox(NULL, TranslateT("An SMS with registration-code will be sent to your mobile phone.\nNotice that you are not able to use the real WhatsApp and this plugin simultaneousley!\nContinue?"), - PRODUCT_NAME, MB_YESNO) == IDYES) - { - proto->Register(REG_STATE_REQ_CODE, string(cc), string(number), string()); - } - } - else if (LOWORD(wparam) == IDC_BUTTON_REGISTER) - { - char code[7]; - if (SendDlgItemMessage(hwnd, IDC_REG_CODE_1, WM_GETTEXTLENGTH, 0, 0) == 3 && - SendDlgItemMessage(hwnd, IDC_REG_CODE_2, WM_GETTEXTLENGTH, 0, 0) == 3) - { - GetDlgItemTextA(hwnd, IDC_REG_CODE_1, code, 4); - GetDlgItemTextA(hwnd, IDC_REG_CODE_2, &(code[3]), 4); - } - else - { - MessageBox(NULL, TranslateT("Please correctly specify your registration code received by SMS"), - PRODUCT_NAME, MB_ICONEXCLAMATION); - return TRUE; - } - string pw = proto->Register(REG_STATE_REG_CODE, string(cc), string(number), string(code)); - if (!pw.empty()) + if (LOWORD(wparam) == IDC_BUTTON_REQUEST_CODE || LOWORD(wparam) == IDC_BUTTON_REGISTER) + { + proto = reinterpret_cast(GetWindowLongPtr(hwnd,GWLP_USERDATA)); + + char cc[5]; + GetDlgItemTextA(hwnd, IDC_CC, cc, sizeof(cc)); + char number[128]; + GetDlgItemTextA(hwnd, IDC_LOGIN, number, sizeof(number)); + + if (LOWORD(wparam) == IDC_BUTTON_REQUEST_CODE) + { + if (MessageBox(NULL, TranslateT("An SMS with registration-code will be sent to your mobile phone.\nNotice that you are not able to use the real WhatsApp and this plugin simultaneousley!\nContinue?"), + PRODUCT_NAME, MB_YESNO) == IDYES) + { + proto->Register(REG_STATE_REQ_CODE, string(cc), string(number), string()); + } + } + else if (LOWORD(wparam) == IDC_BUTTON_REGISTER) { - SetDlgItemTextA(hwnd, IDC_PW, pw.c_str()); - CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(pw.c_str()), (LPARAM)pw.c_str()); - db_set_s(NULL, proto->ModuleName(), WHATSAPP_KEY_PASS, pw.c_str()); - MessageBox(NULL, TranslateT("Your password has been set automatically.\nIf you change your password manually you may lose it and need to request a new code!"), PRODUCT_NAME, MB_ICONWARNING); - } - } - } + char code[7]; + if (SendDlgItemMessage(hwnd, IDC_REG_CODE_1, WM_GETTEXTLENGTH, 0, 0) == 3 && + SendDlgItemMessage(hwnd, IDC_REG_CODE_2, WM_GETTEXTLENGTH, 0, 0) == 3) + { + GetDlgItemTextA(hwnd, IDC_REG_CODE_1, code, 4); + GetDlgItemTextA(hwnd, IDC_REG_CODE_2, &(code[3]), 4); + } + else + { + MessageBox(NULL, TranslateT("Please correctly specify your registration code received by SMS"), + PRODUCT_NAME, MB_ICONEXCLAMATION); + return TRUE; + } + string pw = proto->Register(REG_STATE_REG_CODE, string(cc), string(number), string(code)); + if (!pw.empty()) + { + SetDlgItemTextA(hwnd, IDC_PW, pw.c_str()); + CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(pw.c_str()), (LPARAM)pw.c_str()); + db_set_s(NULL, proto->ModuleName(), WHATSAPP_KEY_PASS, pw.c_str()); + MessageBox(NULL, TranslateT("Your password has been set automatically.\nIf you change your password manually you may lose it and need to request a new code!"), PRODUCT_NAME, MB_ICONWARNING); + } + } + } if ( HIWORD( wparam ) == EN_CHANGE && reinterpret_cast(lparam) == GetFocus()) { switch(LOWORD(wparam)) { - case IDC_CC: + case IDC_CC: case IDC_LOGIN: - case IDC_NICK: + case IDC_NICK: case IDC_PW: SendMessage(GetParent(hwnd),PSM_CHANGED,0,0); } @@ -134,7 +133,6 @@ INT_PTR CALLBACK WhatsAppAccountProc( HWND hwnd, UINT message, WPARAM wparam, LP } return FALSE; - } INT_PTR CALLBACK WhatsAppInputBoxProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) @@ -151,18 +149,18 @@ INT_PTR CALLBACK WhatsAppInputBoxProc( HWND hwnd, UINT message, WPARAM wparam, L ib = reinterpret_cast(lparam); SetWindowLongPtr(hwnd,GWLP_USERDATA,lparam); SendDlgItemMessage(hwnd,IDC_VALUE,EM_LIMITTEXT,ib->limit,0); - SetDlgItemText(hwnd, IDC_VALUE, ib->defaultValue.c_str()); - SetDlgItemText(hwnd, IDC_TEXT, ib->text.c_str()); + SetDlgItemText(hwnd, IDC_VALUE, ib->defaultValue.c_str()); + SetDlgItemText(hwnd, IDC_TEXT, ib->text.c_str()); - /* - DBVARIANT dbv = { DBVT_TCHAR }; + /* + DBVARIANT dbv = { DBVT_TCHAR }; if (!DBGetContactSettingTString(NULL,ib->proto->m_szModuleName,WHATSAPP_KEY_PUSH_NAME,&dbv)) { SetWindowText( hwnd, dbv.ptszVal ); db_free( &dbv ); } - */ - SetWindowText(hwnd, ib->title.c_str()); + */ + SetWindowText(hwnd, ib->title.c_str()); } EnableWindow(GetDlgItem( hwnd, IDC_OK ), FALSE); @@ -171,7 +169,7 @@ INT_PTR CALLBACK WhatsAppInputBoxProc( HWND hwnd, UINT message, WPARAM wparam, L case WM_COMMAND: if ( LOWORD( wparam ) == IDC_VALUE && HIWORD( wparam ) == EN_CHANGE ) { - ib = reinterpret_cast(GetWindowLongPtr(hwnd,GWLP_USERDATA)); + ib = reinterpret_cast(GetWindowLongPtr(hwnd,GWLP_USERDATA)); size_t len = SendDlgItemMessage(hwnd,IDC_VALUE,WM_GETTEXTLENGTH,0,0); TCHAR str[4]; _sntprintf( str, 4, TEXT( "%d" ), ib->limit - len ); @@ -182,26 +180,26 @@ INT_PTR CALLBACK WhatsAppInputBoxProc( HWND hwnd, UINT message, WPARAM wparam, L } else if ( LOWORD( wparam ) == IDC_OK ) { - ib = reinterpret_cast(GetWindowLongPtr(hwnd,GWLP_USERDATA)); + ib = reinterpret_cast(GetWindowLongPtr(hwnd,GWLP_USERDATA)); TCHAR* value = new TCHAR[ib->limit+1]; GetDlgItemText(hwnd,IDC_VALUE,value, ib->limit + 1); ShowWindow(hwnd,SW_HIDE); - input_box_ret* ret = new input_box_ret; - ret->userData = ib->userData; - ret->value = mir_utf8encodeT(value); - delete value; + input_box_ret* ret = new input_box_ret; + ret->userData = ib->userData; + ret->value = mir_utf8encodeT(value); + delete value; ForkThread(ib->thread, ib->proto, ret); EndDialog(hwnd, wparam); - delete ib; + delete ib; return TRUE; } else if ( LOWORD( wparam ) == IDC_CANCEL ) { EndDialog(hwnd, wparam); - ib = reinterpret_cast(GetWindowLongPtr(hwnd,GWLP_USERDATA)); - delete ib; + ib = reinterpret_cast(GetWindowLongPtr(hwnd,GWLP_USERDATA)); + delete ib; return TRUE; } break; diff --git a/protocols/WhatsApp/src/main.cpp b/protocols/WhatsApp/src/main.cpp index 2545bb6736..8cff6e9715 100644 --- a/protocols/WhatsApp/src/main.cpp +++ b/protocols/WhatsApp/src/main.cpp @@ -72,7 +72,7 @@ extern "C" int __declspec(dllexport) Load(void) mir_getLP(&pluginInfo); pcli = reinterpret_cast( CallService( - MS_CLIST_RETRIEVE_INTERFACE,0,reinterpret_cast(g_hInstance))); + MS_CLIST_RETRIEVE_INTERFACE,0,reinterpret_cast(g_hInstance))); PROTOCOLDESCRIPTOR pd = { sizeof(pd) }; pd.szName = "WhatsApp"; @@ -95,7 +95,7 @@ extern "C" int __declspec(dllexport) Load(void) agent << "."; agent << (( g_mirandaVersion >> 8) & 0xFF); agent << "."; - agent << (( g_mirandaVersion ) & 0xFF); + agent << (( g_mirandaVersion ) & 0xFF); #ifdef _WIN64 agent << " WhatsApp Protocol x64/"; #else @@ -119,8 +119,8 @@ extern "C" int __declspec(dllexport) Unload(void) g_Instances.destroy(); - delete FMessage::generating_lock; - WASocketConnection::quitNetwork(); + delete FMessage::generating_lock; + WASocketConnection::quitNetwork(); return 0; } diff --git a/protocols/WhatsApp/src/messages.cpp b/protocols/WhatsApp/src/messages.cpp index fff3d6caf5..c05e19de83 100644 --- a/protocols/WhatsApp/src/messages.cpp +++ b/protocols/WhatsApp/src/messages.cpp @@ -9,27 +9,27 @@ int WhatsAppProto::RecvMsg(HANDLE hContact, PROTORECVEVENT *pre) void WhatsAppProto::onMessageForMe(FMessage* paramFMessage, bool paramBoolean) { - bool isChatRoom = !paramFMessage->remote_resource.empty(); - - std::string* msg; - switch (paramFMessage->media_wa_type) - { - case FMessage::WA_TYPE_IMAGE: - case FMessage::WA_TYPE_AUDIO: - case FMessage::WA_TYPE_VIDEO: - msg = ¶mFMessage->media_url; - break; - default: - msg = ¶mFMessage->data; - } - - if (isChatRoom) - { - msg->insert(0, std::string("[").append(paramFMessage->notifyname).append("]: ")); - } - - HANDLE hContact = this->AddToContactList(paramFMessage->key->remote_jid, 0, false, - isChatRoom ? NULL : paramFMessage->notifyname.c_str(), isChatRoom); + bool isChatRoom = !paramFMessage->remote_resource.empty(); + + std::string* msg; + switch (paramFMessage->media_wa_type) + { + case FMessage::WA_TYPE_IMAGE: + case FMessage::WA_TYPE_AUDIO: + case FMessage::WA_TYPE_VIDEO: + msg = ¶mFMessage->media_url; + break; + default: + msg = ¶mFMessage->data; + } + + if (isChatRoom) + { + msg->insert(0, std::string("[").append(paramFMessage->notifyname).append("]: ")); + } + + HANDLE hContact = this->AddToContactList(paramFMessage->key->remote_jid, 0, false, + isChatRoom ? NULL : paramFMessage->notifyname.c_str(), isChatRoom); PROTORECVEVENT recv = {0}; recv.flags = PREF_UTF; @@ -37,75 +37,75 @@ void WhatsAppProto::onMessageForMe(FMessage* paramFMessage, bool paramBoolean) recv.timestamp = paramFMessage->timestamp; //time(NULL); ProtoChainRecvMsg(hContact, &recv); - this->connection->sendMessageReceived(paramFMessage); + this->connection->sendMessageReceived(paramFMessage); } int WhatsAppProto::SendMsg(HANDLE hContact, int flags, const char *msg) { - LOG(""); + LOG(""); int msgId = ++(this->msgId); - ForkThread( &WhatsAppProto::SendMsgWorker, this, new send_direct(hContact, msg, (HANDLE) msgId, flags & IS_CHAT)); - return this->msgIdHeader + msgId; + ForkThread( &WhatsAppProto::SendMsgWorker, this, new send_direct(hContact, msg, (HANDLE) msgId, flags & IS_CHAT)); + return this->msgIdHeader + msgId; } void WhatsAppProto::SendMsgWorker(void* p) { - LOG(""); - if (p == NULL) - return; - - DBVARIANT dbv; - send_direct *data = static_cast(p); - - if (db_get_b(data->hContact, m_szModuleName, "SimpleChatRoom", 0) > 0 && - db_get_b(data->hContact, m_szModuleName, "IsGroupMember", 0) == 0) - { - LOG("not a group member"); - ProtoBroadcastAck(m_szModuleName,data->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, - (HANDLE) (this->msgIdHeader + this->msgId), (LPARAM) "You cannot send messages to groups if you are not a member."); - } - else if (!db_get_s(data->hContact, m_szModuleName,"ID", &dbv, DBVT_ASCIIZ) && - this->connection != NULL) - { - try - { - db_set_dw(data->hContact, m_szModuleName, WHATSAPP_KEY_LAST_MSG_STATE, 2); - db_set_dw(data->hContact, m_szModuleName, WHATSAPP_KEY_LAST_MSG_ID_HEADER, this->msgIdHeader); - db_set_dw(data->hContact, m_szModuleName, WHATSAPP_KEY_LAST_MSG_ID, this->msgId); - - std::stringstream ss; - ss << this->msgIdHeader << "-" << this->msgId; - Key* key = new Key(Key(dbv.pszVal, true, ss.str())); // deleted by FMessage - FMessage fmsg(key); - fmsg.data = data->msg; - fmsg.timestamp = time(NULL); - - db_free(&dbv); - - this->connection->sendMessage(&fmsg); - } - catch (exception &e) - { - LOG("exception: %s", e.what()); - ProtoBroadcastAck(m_szModuleName,data->hContact,ACKTYPE_MESSAGE,ACKRESULT_FAILED, - (HANDLE) (this->msgIdHeader + this->msgId), (LPARAM) e.what()); - } - catch (...) - { - LOG("unknown exception"); - ProtoBroadcastAck(m_szModuleName,data->hContact,ACKTYPE_MESSAGE,ACKRESULT_FAILED, - (HANDLE) (this->msgIdHeader + this->msgId), (LPARAM) "Failed sending message"); - } - } - else - { - LOG("No connection"); - ProtoBroadcastAck(m_szModuleName,data->hContact,ACKTYPE_MESSAGE,ACKRESULT_FAILED, - (HANDLE) (this->msgIdHeader + this->msgId), (LPARAM) "You cannot send messages when you are offline."); - } - - delete data; + LOG(""); + if (p == NULL) + return; + + DBVARIANT dbv; + send_direct *data = static_cast(p); + + if (db_get_b(data->hContact, m_szModuleName, "SimpleChatRoom", 0) > 0 && + db_get_b(data->hContact, m_szModuleName, "IsGroupMember", 0) == 0) + { + LOG("not a group member"); + ProtoBroadcastAck(m_szModuleName,data->hContact, ACKTYPE_MESSAGE, ACKRESULT_FAILED, + (HANDLE) (this->msgIdHeader + this->msgId), (LPARAM) "You cannot send messages to groups if you are not a member."); + } + else if (!db_get_s(data->hContact, m_szModuleName,"ID", &dbv, DBVT_ASCIIZ) && + this->connection != NULL) + { + try + { + db_set_dw(data->hContact, m_szModuleName, WHATSAPP_KEY_LAST_MSG_STATE, 2); + db_set_dw(data->hContact, m_szModuleName, WHATSAPP_KEY_LAST_MSG_ID_HEADER, this->msgIdHeader); + db_set_dw(data->hContact, m_szModuleName, WHATSAPP_KEY_LAST_MSG_ID, this->msgId); + + std::stringstream ss; + ss << this->msgIdHeader << "-" << this->msgId; + Key* key = new Key(Key(dbv.pszVal, true, ss.str())); // deleted by FMessage + FMessage fmsg(key); + fmsg.data = data->msg; + fmsg.timestamp = time(NULL); + + db_free(&dbv); + + this->connection->sendMessage(&fmsg); + } + catch (exception &e) + { + LOG("exception: %s", e.what()); + ProtoBroadcastAck(m_szModuleName,data->hContact,ACKTYPE_MESSAGE,ACKRESULT_FAILED, + (HANDLE) (this->msgIdHeader + this->msgId), (LPARAM) e.what()); + } + catch (...) + { + LOG("unknown exception"); + ProtoBroadcastAck(m_szModuleName,data->hContact,ACKTYPE_MESSAGE,ACKRESULT_FAILED, + (HANDLE) (this->msgIdHeader + this->msgId), (LPARAM) "Failed sending message"); + } + } + else + { + LOG("No connection"); + ProtoBroadcastAck(m_szModuleName,data->hContact,ACKTYPE_MESSAGE,ACKRESULT_FAILED, + (HANDLE) (this->msgIdHeader + this->msgId), (LPARAM) "You cannot send messages when you are offline."); + } + + delete data; } void WhatsAppProto::RecvMsgWorker(void *p) @@ -113,21 +113,21 @@ void WhatsAppProto::RecvMsgWorker(void *p) if (p == NULL) return; - //WAConnection.cpp l1225 - message will be deleted. We cannot send the ack inside a thread! + //WAConnection.cpp l1225 - message will be deleted. We cannot send the ack inside a thread! //FMessage *fmsg = static_cast(p); - //this->connection->sendMessageReceived(fmsg); + //this->connection->sendMessageReceived(fmsg); //delete fmsg; } void WhatsAppProto::onIsTyping(const std::string& paramString, bool paramBoolean) { - HANDLE hContact = this->AddToContactList(paramString, 0, false); - if (hContact != NULL) - { - CallService(MS_PROTO_CONTACTISTYPING, (WPARAM) hContact, (LPARAM) - paramBoolean ? PROTOTYPE_CONTACTTYPING_INFINITE : PROTOTYPE_CONTACTTYPING_OFF); - } + HANDLE hContact = this->AddToContactList(paramString, 0, false); + if (hContact != NULL) + { + CallService(MS_PROTO_CONTACTISTYPING, (WPARAM) hContact, (LPARAM) + paramBoolean ? PROTOTYPE_CONTACTTYPING_INFINITE : PROTOTYPE_CONTACTTYPING_OFF); + } } @@ -152,13 +152,13 @@ void WhatsAppProto::SendTypingWorker(void* p) DBVARIANT dbv; if ( !db_get_s(typing->hContact,m_szModuleName,WHATSAPP_KEY_ID,&dbv, DBVT_ASCIIZ) && - this->isOnline()) + this->isOnline()) { - if (typing->status == PROTOTYPE_SELFTYPING_ON) { - this->connection->sendComposing(dbv.pszVal); - } else { - this->connection->sendPaused(dbv.pszVal); - } + if (typing->status == PROTOTYPE_SELFTYPING_ON) { + this->connection->sendComposing(dbv.pszVal); + } else { + this->connection->sendPaused(dbv.pszVal); + } } delete typing; @@ -166,35 +166,35 @@ void WhatsAppProto::SendTypingWorker(void* p) void WhatsAppProto::onMessageStatusUpdate(FMessage* fmsg) { - LOG(""); - - HANDLE hContact = this->ContactIDToHContact(fmsg->key->remote_jid); - if (hContact == 0) - return; - - int state = 5 - fmsg->status; - if (state != 0 && state != 1) - return; - - int header; - int id; - size_t delimPos = fmsg->key->id.find("-"); - - std::stringstream ss; - ss << fmsg->key->id.substr(0, delimPos); - ss >> header; - - ss.clear(); - ss << fmsg->key->id.substr(delimPos + 1); - ss >> id; - - if (state == 1) - ProtoBroadcastAck(m_szModuleName, hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE) (header + id),0); - - if (db_get_dw(hContact, m_szModuleName, WHATSAPP_KEY_LAST_MSG_ID_HEADER, 0) == header && - db_get_dw(hContact, m_szModuleName, WHATSAPP_KEY_LAST_MSG_ID, -1) == id) - { - db_set_dw(hContact, m_szModuleName, WHATSAPP_KEY_LAST_MSG_STATE, state); - this->UpdateStatusMsg(hContact); - } + LOG(""); + + HANDLE hContact = this->ContactIDToHContact(fmsg->key->remote_jid); + if (hContact == 0) + return; + + int state = 5 - fmsg->status; + if (state != 0 && state != 1) + return; + + int header; + int id; + size_t delimPos = fmsg->key->id.find("-"); + + std::stringstream ss; + ss << fmsg->key->id.substr(0, delimPos); + ss >> header; + + ss.clear(); + ss << fmsg->key->id.substr(delimPos + 1); + ss >> id; + + if (state == 1) + ProtoBroadcastAck(m_szModuleName, hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE) (header + id),0); + + if (db_get_dw(hContact, m_szModuleName, WHATSAPP_KEY_LAST_MSG_ID_HEADER, 0) == header && + db_get_dw(hContact, m_szModuleName, WHATSAPP_KEY_LAST_MSG_ID, -1) == id) + { + db_set_dw(hContact, m_szModuleName, WHATSAPP_KEY_LAST_MSG_STATE, state); + this->UpdateStatusMsg(hContact); + } } \ No newline at end of file diff --git a/protocols/WhatsApp/src/proto.cpp b/protocols/WhatsApp/src/proto.cpp index 260122efa1..657a15a18d 100644 --- a/protocols/WhatsApp/src/proto.cpp +++ b/protocols/WhatsApp/src/proto.cpp @@ -2,45 +2,45 @@ WhatsAppProto::WhatsAppProto(const char* proto_name, const TCHAR* username) { - ProtoConstructor(this, proto_name, username); + ProtoConstructor(this, proto_name, username); - this->challenge = new std::vector; - this->msgId = 0; - this->msgIdHeader = time(NULL); + this->challenge = new std::vector; + this->msgId = 0; + this->msgIdHeader = time(NULL); - update_loop_lock_ = CreateEvent(NULL, false, false, NULL); - FMessage::generating_lock = new Mutex(); + update_loop_lock_ = CreateEvent(NULL, false, false, NULL); + FMessage::generating_lock = new Mutex(); - CreateProtoService(m_szModuleName, PS_CREATEACCMGRUI, &WhatsAppProto::SvcCreateAccMgrUI, this); + CreateProtoService(m_szModuleName, PS_CREATEACCMGRUI, &WhatsAppProto::SvcCreateAccMgrUI, this); CreateProtoService(m_szModuleName, PS_JOINCHAT, &WhatsAppProto::OnJoinChat, this); CreateProtoService(m_szModuleName, PS_LEAVECHAT, &WhatsAppProto::OnLeaveChat, this); - HookProtoEvent(ME_CLIST_PREBUILDSTATUSMENU, &WhatsAppProto::OnBuildStatusMenu, this); - HookProtoEvent(ME_GC_EVENT, &WhatsAppProto::OnChatOutgoing, this); + HookProtoEvent(ME_CLIST_PREBUILDSTATUSMENU, &WhatsAppProto::OnBuildStatusMenu, this); + HookProtoEvent(ME_GC_EVENT, &WhatsAppProto::OnChatOutgoing, this); - this->InitContactMenus(); + this->InitContactMenus(); - // Create standard network connection - TCHAR descr[512]; - NETLIBUSER nlu = {sizeof(nlu)}; - nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS; + // Create standard network connection + TCHAR descr[512]; + NETLIBUSER nlu = {sizeof(nlu)}; + nlu.flags = NUF_INCOMING | NUF_OUTGOING | NUF_HTTPCONNS; char module[512]; mir_snprintf(module, SIZEOF(module), "%s", m_szModuleName); nlu.szSettingsModule = module; 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); + + WASocketConnection::initNetwork(m_hNetlibUser); TCHAR *profile = Utils_ReplaceVarsT( _T("%miranda_avatarcache%")); def_avatar_folder_ = std::tstring(profile) + _T("\\") + m_tszUserName; mir_free(profile); hAvatarFolder_ = FoldersRegisterCustomPathT(m_szModuleName, "Avatars", def_avatar_folder_.c_str()); - // Register group chat + // Register group chat GCREGISTER gcr = {0}; gcr.cbSize = sizeof(GCREGISTER); gcr.dwFlags = GC_TYPNOTIF | GC_CHANMGR | GC_TCHAR; @@ -54,42 +54,42 @@ WhatsAppProto::WhatsAppProto(const char* proto_name, const TCHAR* username) //HookProtoEvent(ME_GC_EVENT, &CMsnProto::MSN_GCEventHook); //HookProtoEvent(ME_GC_BUILDMENU, &CMsnProto::MSN_GCMenuHook); - SetAllContactStatuses(ID_STATUS_OFFLINE, true); + SetAllContactStatuses(ID_STATUS_OFFLINE, true); } WhatsAppProto::~WhatsAppProto() { - CloseHandle(update_loop_lock_); + CloseHandle(update_loop_lock_); - if (this->challenge != NULL) - delete this->challenge; + if (this->challenge != NULL) + delete this->challenge; - ProtoDestructor(this); + ProtoDestructor(this); } DWORD_PTR WhatsAppProto::GetCaps( int type, HANDLE 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"; + 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"; } return 0; } @@ -110,7 +110,7 @@ int WhatsAppProto::SetStatus( int new_status ) case ID_STATUS_CONNECTING: m_iDesiredStatus = ID_STATUS_OFFLINE; break; - */ + */ case ID_STATUS_IDLE: default: @@ -142,12 +142,12 @@ int WhatsAppProto::SetStatus( int new_status ) HANDLE WhatsAppProto::AddToList( int flags, PROTOSEARCHRESULT* psr ) { - return NULL; + return NULL; } int WhatsAppProto::AuthRequest(HANDLE hContact,const PROTOCHAR *message) { - return this->RequestFriendship((WPARAM)hContact, NULL); + return this->RequestFriendship((WPARAM)hContact, NULL); } int WhatsAppProto::Authorize(HANDLE hDbEvent) @@ -168,90 +168,90 @@ HANDLE WhatsAppProto::SearchBasic( const PROTOCHAR* id ) string WhatsAppProto::Register(int state, string cc, string number, string code) { - string idx; - string ret; - DBVARIANT dbv; + string idx; + string ret; + DBVARIANT dbv; - if ( WASocketConnection::hNetlibUser == NULL) - { - NotifyEvent(m_tszUserName, TranslateT("Network-connection error."), NULL, WHATSAPP_EVENT_CLIENT); - return ret; - } + if ( WASocketConnection::hNetlibUser == NULL) + { + NotifyEvent(m_tszUserName, TranslateT("Network-connection error."), NULL, WHATSAPP_EVENT_CLIENT); + return ret; + } - /* + /* if ( !db_get_s(NULL,m_szModuleName,WHATSAPP_KEY_CC,&dbv, DBVT_ASCIIZ)) { cc = dbv.pszVal; db_free(&dbv); if (cc.empty()) - { - NotifyEvent(m_tszUserName,TranslateT("Please enter a country-code."),NULL,WHATSAPP_EVENT_CLIENT); - return; - } + { + NotifyEvent(m_tszUserName,TranslateT("Please enter a country-code."),NULL,WHATSAPP_EVENT_CLIENT); + return; + } } - if ( !db_get_s(NULL,m_szModuleName,WHATSAPP_KEY_LOGIN,&dbv, DBVT_ASCIIZ)) + if ( !db_get_s(NULL,m_szModuleName,WHATSAPP_KEY_LOGIN,&dbv, DBVT_ASCIIZ)) { number = dbv.pszVal; db_free(&dbv); if (number.empty()) - { - NotifyEvent(m_tszUserName,TranslateT("Please enter a phone-number without country-code."),NULL,WHATSAPP_EVENT_CLIENT); - return; - } + { + NotifyEvent(m_tszUserName,TranslateT("Please enter a phone-number without country-code."),NULL,WHATSAPP_EVENT_CLIENT); + return; + } + } + */ + if ( !db_get_s(NULL,m_szModuleName,WHATSAPP_KEY_IDX,&dbv,DBVT_ASCIIZ)) + { + idx = dbv.pszVal; + db_free(&dbv); } - */ - if ( !db_get_s(NULL,m_szModuleName,WHATSAPP_KEY_IDX,&dbv,DBVT_ASCIIZ)) - { - idx = dbv.pszVal; - db_free(&dbv); - } - if (idx.empty()) - { - std::stringstream tm; - tm << time(NULL); - BYTE idxBuf[16]; + if (idx.empty()) + { + std::stringstream tm; + tm << time(NULL); + BYTE idxBuf[16]; utils::md5string(tm.str(), idxBuf); - idx = std::string((const char*) idxBuf, 16); - db_set_s(0, m_szModuleName,WHATSAPP_KEY_IDX, idx.c_str()); - } - - string url; - if (state == REG_STATE_REQ_CODE) - { - string token(Utilities::md5String(std::string(ACCOUNT_TOKEN_PREFIX1) + ACCOUNT_TOKEN_PREFIX2 + number)); - url = string(ACCOUNT_URL_CODEREQUESTV2); - url += "?lc=US&lg=en&mcc=000&mnc=000&method=sms&token="+ token; - } - else if (state == REG_STATE_REG_CODE) - { - url = string(ACCOUNT_URL_REGISTERREQUESTV2); - url += "?code="+ code; - } - url += "&cc="+ cc +"&in="+ number +"&id="+ idx; - - NETLIBHTTPHEADER agentHdr; - agentHdr.szName = "User-Agent"; - agentHdr.szValue = ACCOUNT_USER_AGENT_REGISTRATION; - - NETLIBHTTPHEADER acceptHdr; - acceptHdr.szName = "Accept"; - acceptHdr.szValue = "text/json"; - - NETLIBHTTPHEADER ctypeHdr; - ctypeHdr.szName = "Content-Type"; - ctypeHdr.szValue = "application/x-www-form-urlencoded"; - - NETLIBHTTPHEADER headers[] = { agentHdr, acceptHdr, ctypeHdr }; - - NETLIBHTTPREQUEST nlhr = {sizeof(NETLIBHTTPREQUEST)}; - nlhr.requestType = REQUEST_POST; - nlhr.szUrl = (char*) url.c_str(); - nlhr.headers = &headers[0]; - nlhr.headersCount = 3; - nlhr.flags = NLHRF_HTTP11 | NLHRF_GENERATEHOST | NLHRF_REMOVEHOST | NLHRF_SSL; - - NETLIBHTTPREQUEST* pnlhr = (NETLIBHTTPREQUEST*) CallService(MS_NETLIB_HTTPTRANSACTION, - (WPARAM) WASocketConnection::hNetlibUser, (LPARAM)&nlhr); + idx = std::string((const char*) idxBuf, 16); + db_set_s(0, m_szModuleName,WHATSAPP_KEY_IDX, idx.c_str()); + } + + string url; + if (state == REG_STATE_REQ_CODE) + { + string token(Utilities::md5String(std::string(ACCOUNT_TOKEN_PREFIX1) + ACCOUNT_TOKEN_PREFIX2 + number)); + url = string(ACCOUNT_URL_CODEREQUESTV2); + url += "?lc=US&lg=en&mcc=000&mnc=000&method=sms&token="+ token; + } + else if (state == REG_STATE_REG_CODE) + { + url = string(ACCOUNT_URL_REGISTERREQUESTV2); + url += "?code="+ code; + } + url += "&cc="+ cc +"&in="+ number +"&id="+ idx; + + NETLIBHTTPHEADER agentHdr; + agentHdr.szName = "User-Agent"; + agentHdr.szValue = ACCOUNT_USER_AGENT_REGISTRATION; + + NETLIBHTTPHEADER acceptHdr; + acceptHdr.szName = "Accept"; + acceptHdr.szValue = "text/json"; + + NETLIBHTTPHEADER ctypeHdr; + ctypeHdr.szName = "Content-Type"; + ctypeHdr.szValue = "application/x-www-form-urlencoded"; + + NETLIBHTTPHEADER headers[] = { agentHdr, acceptHdr, ctypeHdr }; + + NETLIBHTTPREQUEST nlhr = {sizeof(NETLIBHTTPREQUEST)}; + nlhr.requestType = REQUEST_POST; + nlhr.szUrl = (char*) url.c_str(); + nlhr.headers = &headers[0]; + nlhr.headersCount = 3; + nlhr.flags = NLHRF_HTTP11 | NLHRF_GENERATEHOST | NLHRF_REMOVEHOST | NLHRF_SSL; + + NETLIBHTTPREQUEST* pnlhr = (NETLIBHTTPREQUEST*) CallService(MS_NETLIB_HTTPTRANSACTION, + (WPARAM) WASocketConnection::hNetlibUser, (LPARAM)&nlhr); string title = this->TranslateStr("Registration"); if (pnlhr == NULL) { @@ -259,63 +259,63 @@ string WhatsAppProto::Register(int state, string cc, string number, string code) return ret; } - LOG("Server response: %s", pnlhr->pData); - MessageBoxA(NULL, pnlhr->pData, "Debug", MB_OK); - - cJSON* resp = cJSON_Parse(pnlhr->pData); - cJSON* val; - - // Invalid - if (resp == NULL) - { - this->NotifyEvent(title, this->TranslateStr("Registration failed. Invalid server response."), NULL, WHATSAPP_EVENT_CLIENT); - return ret; - } - - // Status = fail - val = cJSON_GetObjectItem(resp, "status"); - if (strcmp(val->valuestring, "fail") == 0) - { - cJSON* tmpVal = cJSON_GetObjectItem(resp, "reason"); - if (strcmp(tmpVal->valuestring, "stale") == 0) - { - this->NotifyEvent(title, this->TranslateStr("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); - } - - tmpVal = cJSON_GetObjectItem(resp, "retry_after"); - if (tmpVal != NULL) - { - this->NotifyEvent(title, this->TranslateStr("Please try again in %i seconds", tmpVal->valueint), NULL, WHATSAPP_EVENT_OTHER); - } - } - - // Request code - else if (state == REG_STATE_REQ_CODE) - { - if (strcmp(val->valuestring, "sent") == 0) - { - this->NotifyEvent(title, this->TranslateStr("Registration code has been sent to your phone."), NULL, WHATSAPP_EVENT_OTHER); - } - } - - // Register - else if (state == REG_STATE_REG_CODE) - { - val = cJSON_GetObjectItem(resp, "pw"); - if (val == NULL) - { - this->NotifyEvent(title, this->TranslateStr("Registration failed."), NULL, WHATSAPP_EVENT_CLIENT); - } else - ret = val->valuestring; - } - - cJSON_Delete(resp); - - return ret; + LOG("Server response: %s", pnlhr->pData); + MessageBoxA(NULL, pnlhr->pData, "Debug", MB_OK); + + cJSON* resp = cJSON_Parse(pnlhr->pData); + cJSON* val; + + // Invalid + if (resp == NULL) + { + this->NotifyEvent(title, this->TranslateStr("Registration failed. Invalid server response."), NULL, WHATSAPP_EVENT_CLIENT); + return ret; + } + + // Status = fail + val = cJSON_GetObjectItem(resp, "status"); + if (strcmp(val->valuestring, "fail") == 0) + { + cJSON* tmpVal = cJSON_GetObjectItem(resp, "reason"); + if (strcmp(tmpVal->valuestring, "stale") == 0) + { + this->NotifyEvent(title, this->TranslateStr("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); + } + + tmpVal = cJSON_GetObjectItem(resp, "retry_after"); + if (tmpVal != NULL) + { + this->NotifyEvent(title, this->TranslateStr("Please try again in %i seconds", tmpVal->valueint), NULL, WHATSAPP_EVENT_OTHER); + } + } + + // Request code + else if (state == REG_STATE_REQ_CODE) + { + if (strcmp(val->valuestring, "sent") == 0) + { + this->NotifyEvent(title, this->TranslateStr("Registration code has been sent to your phone."), NULL, WHATSAPP_EVENT_OTHER); + } + } + + // Register + else if (state == REG_STATE_REG_CODE) + { + val = cJSON_GetObjectItem(resp, "pw"); + if (val == NULL) + { + this->NotifyEvent(title, this->TranslateStr("Registration failed."), NULL, WHATSAPP_EVENT_CLIENT); + } else + ret = val->valuestring; + } + + cJSON_Delete(resp); + + return ret; } ////////////////////////////////////////////////////////////////////////////// @@ -329,12 +329,12 @@ int WhatsAppProto::SvcCreateAccMgrUI(WPARAM wParam,LPARAM lParam) int WhatsAppProto::RefreshBuddyList(WPARAM, LPARAM ) { - LOG(""); - if (!isOffline()) - { - //ForkThread( - } - return 0; + LOG(""); + if (!isOffline()) + { + //ForkThread( + } + return 0; } int WhatsAppProto::RequestFriendship(WPARAM wParam, LPARAM lParam) @@ -348,8 +348,8 @@ int WhatsAppProto::RequestFriendship(WPARAM wParam, LPARAM lParam) if ( !db_get_s(hContact,m_szModuleName,WHATSAPP_KEY_ID,&dbv, DBVT_ASCIIZ)) { std::string id(dbv.pszVal); - this->connection->sendQueryLastOnline(id); - this->connection->sendPresenceSubscriptionRequest(id); + this->connection->sendQueryLastOnline(id); + this->connection->sendPresenceSubscriptionRequest(id); db_free(&dbv); } @@ -395,7 +395,8 @@ LRESULT CALLBACK PopupDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa { // After a click, destroy popup PUDeletePopup(hwnd); - } break; + } + break; case WM_CONTEXTMENU: PUDeletePopup(hwnd); @@ -418,11 +419,11 @@ LRESULT CALLBACK PopupDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa void WhatsAppProto::NotifyEvent(const string& title, const string& info, HANDLE 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); - this->NotifyEvent(rawTitle, rawInfo, contact, flags, url); - mir_free(rawTitle); - mir_free(rawInfo); + 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, HANDLE contact, DWORD flags, TCHAR* szUrl) @@ -431,31 +432,31 @@ void WhatsAppProto::NotifyEvent(TCHAR* title, TCHAR* info, HANDLE contact, DWORD 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_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; + } if ( !getByte(WHATSAPP_KEY_SYSTRAY_NOTIFY,DEFAULT_SYSTRAY_NOTIFY)) { @@ -482,8 +483,8 @@ void WhatsAppProto::NotifyEvent(TCHAR* title, TCHAR* info, HANDLE contact, DWORD MIRANDASYSTRAYNOTIFY err; int niif_flags = flags; REMOVE_FLAG( niif_flags, WHATSAPP_EVENT_CLIENT | - WHATSAPP_EVENT_NOTIFICATION | - WHATSAPP_EVENT_OTHER ); + WHATSAPP_EVENT_NOTIFICATION | + WHATSAPP_EVENT_OTHER ); err.szProto = m_szModuleName; err.cbSize = sizeof(err); err.dwInfoFlags = NIIF_INTERN_TCHAR | niif_flags; @@ -507,9 +508,9 @@ exit: 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; + 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 diff --git a/protocols/WhatsApp/src/theme.cpp b/protocols/WhatsApp/src/theme.cpp index 56680016a1..a457f9a603 100644 --- a/protocols/WhatsApp/src/theme.cpp +++ b/protocols/WhatsApp/src/theme.cpp @@ -1,16 +1,16 @@ -#include "common.h" + #include "common.h" extern OBJLIST g_Instances; static IconItem icons[] = { - { LPGEN("WhatsApp Icon"), "whatsApp", IDI_WHATSAPP }, - { LPGEN("Add To Group"), "addContactToGroup", IDI_ADD_USER_TO_GROUP}, - { LPGEN("Create Chat Group"), "createGroup", IDI_ADD_GROUP }, - { LPGEN("Remove From Chat Group"), "removeContactFromGroup", IDI_REMOVE_USER_FROM_GROUP }, - { LPGEN("Leave And Delete Group"), "leaveAndDeleteGroup", IDI_LEAVE_GROUP }, - { LPGEN("Leave Group"), "leaveGroup", IDI_LEAVE_GROUP }, - { LPGEN("Change Group Subject"), "changeGroupSubject", IDI_CHANGE_GROUP_SUBJECT } + { LPGEN("WhatsApp Icon"), "whatsApp", IDI_WHATSAPP }, + { LPGEN("Add To Group"), "addContactToGroup", IDI_ADD_USER_TO_GROUP}, + { LPGEN("Create Chat Group"), "createGroup", IDI_ADD_GROUP }, + { LPGEN("Remove From Chat Group"), "removeContactFromGroup", IDI_REMOVE_USER_FROM_GROUP }, + { LPGEN("Leave And Delete Group"), "leaveAndDeleteGroup", IDI_LEAVE_GROUP }, + { LPGEN("Leave Group"), "leaveGroup", IDI_LEAVE_GROUP }, + { LPGEN("Change Group Subject"), "changeGroupSubject", IDI_CHANGE_GROUP_SUBJECT } }; void InitIcons(void) @@ -84,30 +84,30 @@ static int PrebuildContactMenu(WPARAM wParam,LPARAM lParam) void WhatsAppProto::InitContactMenus() { - hHookPreBuildMenu = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, PrebuildContactMenu); + hHookPreBuildMenu = HookEvent(ME_CLIST_PREBUILDCONTACTMENU, PrebuildContactMenu); - CLISTMENUITEM mi = {sizeof(mi)}; + CLISTMENUITEM mi = {sizeof(mi)}; - mi.position = -2000006100; + mi.position = -2000006100; mi.icolibItem = GetIconHandle("leaveGroup"); mi.pszName = GetIconDescription("leaveGroup"); mi.pszService = "WhatsAppProto/LeaveGroup"; - g_hContactMenuSvc[CMI_LEAVE_GROUP] = - CreateServiceFunction(mi.pszService,GlobalService<&WhatsAppProto::OnLeaveGroup>); + g_hContactMenuSvc[CMI_LEAVE_GROUP] = + CreateServiceFunction(mi.pszService,GlobalService<&WhatsAppProto::OnLeaveGroup>); g_hContactMenuItems[CMI_LEAVE_GROUP] = Menu_AddContactMenuItem(&mi); - mi.position = -2000006100; + mi.position = -2000006100; mi.icolibItem = GetIconHandle("leaveAndDeleteGroup"); mi.pszName = GetIconDescription("leaveAndDeleteGroup"); - g_hContactMenuSvc[CMI_REMOVE_GROUP] = g_hContactMenuSvc[CMI_LEAVE_GROUP]; + g_hContactMenuSvc[CMI_REMOVE_GROUP] = g_hContactMenuSvc[CMI_LEAVE_GROUP]; g_hContactMenuItems[CMI_REMOVE_GROUP] = Menu_AddContactMenuItem(&mi); - mi.position = -2000006099; + mi.position = -2000006099; mi.icolibItem = GetIconHandle("changeGroupSubject"); mi.pszName = GetIconDescription("changeGroupSubject"); mi.pszService = "WhatsAppProto/ChangeGroupSubject"; - g_hContactMenuSvc[CMI_CHANGE_GROUP_SUBJECT] = - CreateServiceFunction(mi.pszService,GlobalService<&WhatsAppProto::OnChangeGroupSubject>); + g_hContactMenuSvc[CMI_CHANGE_GROUP_SUBJECT] = + CreateServiceFunction(mi.pszService,GlobalService<&WhatsAppProto::OnChangeGroupSubject>); g_hContactMenuItems[CMI_CHANGE_GROUP_SUBJECT] = Menu_AddContactMenuItem(&mi); } @@ -125,134 +125,134 @@ void EnableMenuItem(HANDLE hMenuItem, bool enable) int WhatsAppProto::OnPrebuildContactMenu(WPARAM wParam,LPARAM lParam) { HANDLE hContact = reinterpret_cast(wParam); - if (hContact) - LOG(this->GetContactDisplayName(hContact).c_str()); - else - LOG("No contact found"); - - if (g_hContactMenuItems[CMI_ADD_CONTACT_TO_GROUP] != NULL) - { - CallService("CList/RemoveContactMenuItem", (WPARAM) g_hContactMenuItems[CMI_ADD_CONTACT_TO_GROUP], (LPARAM) 0); - } - if (g_hContactMenuItems[CMI_REMOVE_CONTACT_FROM_GROUP] != NULL) - { - CallService("CList/RemoveContactMenuItem", (WPARAM) g_hContactMenuItems[CMI_REMOVE_CONTACT_FROM_GROUP], (LPARAM) 0); - } - - int chatType = db_get_b(hContact, m_szModuleName, "SimpleChatRoom", 0); - - CLISTMENUITEM mi = {sizeof(mi)}; - - if (chatType == 0) - { - mi.flags = CMIF_CHILDPOPUP; - mi.position= -2000006102; - mi.icolibItem = GetIconHandle("addContactToGroup"); - mi.pszName = GetIconDescription("addContactToGroup"); - mi.pszService = NULL; - g_hContactMenuItems[CMI_ADD_CONTACT_TO_GROUP] = Menu_AddContactMenuItem(&mi); - - if (!isOnline()) - { - mi.flags = CMIM_FLAGS | CMIF_GRAYED; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) g_hContactMenuItems[CMI_ADD_CONTACT_TO_GROUP], (LPARAM) &mi); - return 0; - } - - mi.hParentMenu = (HGENMENU) g_hContactMenuItems[CMI_ADD_CONTACT_TO_GROUP]; - mi.flags = CMIF_ROOTHANDLE | CMIF_TCHAR; - - string fullSvcName; - string svcName = m_szModuleName; - svcName += "/AddContactToGroup_"; - DBVARIANT dbv; - - for (map>::iterator it = this->isMemberByGroupContact.begin(); - it != this->isMemberByGroupContact.end(); ++it) - { - map::iterator memberIt = it->second.find(hContact); - // Only, if current contact is not already member of this group - if ((memberIt == it->second.end() || memberIt->second == false) && - !db_get_s(it->first, m_szModuleName, "ID", &dbv, DBVT_ASCIIZ)) - { - fullSvcName = svcName + dbv.pszVal; - mi.pszService = (char*) fullSvcName.c_str(); - mi.ptszName = mir_a2t_cp(this->GetContactDisplayName(it->first).c_str(), CP_UTF8); - CreateServiceFunctionParam(mi.pszService, GlobalServiceParam<&WhatsAppProto::OnAddContactToGroup>, (LPARAM) it->first); - Menu_AddContactMenuItem(&mi); - db_free(&dbv); - mir_free(mi.ptszName); - } - } - } - else if (chatType == 1) - { - mi.flags = CMIM_FLAGS; - if (!isOnline() || db_get_b(hContact, m_szModuleName, "IsGroupMember", 0) == 0) - { - mi.flags |= CMIF_GRAYED; - } - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) g_hContactMenuItems[CMI_LEAVE_GROUP], (LPARAM) &mi); - } - else if (chatType == 2) - { - // owning chat/group - mi.flags = CMIF_CHILDPOPUP; - mi.position= -2000006102; - mi.icolibItem = GetIconHandle("removeContactFromGroup"); - mi.pszName = GetIconDescription("removeContactFromGroup"); - mi.pszService = NULL; - g_hContactMenuItems[CMI_REMOVE_CONTACT_FROM_GROUP] = Menu_AddContactMenuItem(&mi); - - if (isOnline() && db_get_b(hContact, m_szModuleName, "IsGroupMember", 0) == 1) - { - map>::iterator groupsIt = this->isMemberByGroupContact.find(hContact); - if (groupsIt == this->isMemberByGroupContact.end()) - { - LOG("Group exists only on contact list"); - } - else - { - mi.hParentMenu = (HGENMENU) g_hContactMenuItems[CMI_REMOVE_CONTACT_FROM_GROUP]; - mi.flags = CMIF_ROOTHANDLE | CMIF_TCHAR; - - string fullSvcName; - string svcName = m_szModuleName; - svcName += "/RemoveContactFromGroup_"; - DBVARIANT dbv; - - for (map::iterator it = groupsIt->second.begin(); it != groupsIt->second.end(); ++it) - { - if (!db_get_s(it->first, m_szModuleName, "ID", &dbv, DBVT_ASCIIZ)) - { - fullSvcName = svcName + dbv.pszVal; - mi.pszService = (char*) fullSvcName.c_str(); - mi.ptszName = mir_a2t_cp(this->GetContactDisplayName(it->first).c_str(), CP_UTF8); - CreateServiceFunctionParam(mi.pszService, - GlobalServiceParam<&WhatsAppProto::OnRemoveContactFromGroup>, (LPARAM) it->first); - Menu_AddContactMenuItem(&mi); - db_free(&dbv); - mir_free(mi.ptszName); - } - } - } - mi.flags = CMIM_FLAGS; - } - else - { - mi.flags = CMIM_FLAGS | CMIF_GRAYED; - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) g_hContactMenuItems[CMI_REMOVE_CONTACT_FROM_GROUP], (LPARAM) &mi); - } - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) g_hContactMenuItems[CMI_REMOVE_GROUP], (LPARAM) &mi); - CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) g_hContactMenuItems[CMI_CHANGE_GROUP_SUBJECT], (LPARAM) &mi); - } - - return 0; + if (hContact) + LOG(this->GetContactDisplayName(hContact).c_str()); + else + LOG("No contact found"); + + if (g_hContactMenuItems[CMI_ADD_CONTACT_TO_GROUP] != NULL) + { + CallService("CList/RemoveContactMenuItem", (WPARAM) g_hContactMenuItems[CMI_ADD_CONTACT_TO_GROUP], (LPARAM) 0); + } + if (g_hContactMenuItems[CMI_REMOVE_CONTACT_FROM_GROUP] != NULL) + { + CallService("CList/RemoveContactMenuItem", (WPARAM) g_hContactMenuItems[CMI_REMOVE_CONTACT_FROM_GROUP], (LPARAM) 0); + } + + int chatType = db_get_b(hContact, m_szModuleName, "SimpleChatRoom", 0); + + CLISTMENUITEM mi = {sizeof(mi)}; + + if (chatType == 0) + { + mi.flags = CMIF_CHILDPOPUP; + mi.position= -2000006102; + mi.icolibItem = GetIconHandle("addContactToGroup"); + mi.pszName = GetIconDescription("addContactToGroup"); + mi.pszService = NULL; + g_hContactMenuItems[CMI_ADD_CONTACT_TO_GROUP] = Menu_AddContactMenuItem(&mi); + + if (!isOnline()) + { + mi.flags = CMIM_FLAGS | CMIF_GRAYED; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) g_hContactMenuItems[CMI_ADD_CONTACT_TO_GROUP], (LPARAM) &mi); + return 0; + } + + mi.hParentMenu = (HGENMENU) g_hContactMenuItems[CMI_ADD_CONTACT_TO_GROUP]; + mi.flags = CMIF_ROOTHANDLE | CMIF_TCHAR; + + string fullSvcName; + string svcName = m_szModuleName; + svcName += "/AddContactToGroup_"; + DBVARIANT dbv; + + for (map>::iterator it = this->isMemberByGroupContact.begin(); + it != this->isMemberByGroupContact.end(); ++it) + { + map::iterator memberIt = it->second.find(hContact); + // Only, if current contact is not already member of this group + if ((memberIt == it->second.end() || memberIt->second == false) && + !db_get_s(it->first, m_szModuleName, "ID", &dbv, DBVT_ASCIIZ)) + { + fullSvcName = svcName + dbv.pszVal; + mi.pszService = (char*) fullSvcName.c_str(); + mi.ptszName = mir_a2t_cp(this->GetContactDisplayName(it->first).c_str(), CP_UTF8); + CreateServiceFunctionParam(mi.pszService, GlobalServiceParam<&WhatsAppProto::OnAddContactToGroup>, (LPARAM) it->first); + Menu_AddContactMenuItem(&mi); + db_free(&dbv); + mir_free(mi.ptszName); + } + } + } + else if (chatType == 1) + { + mi.flags = CMIM_FLAGS; + if (!isOnline() || db_get_b(hContact, m_szModuleName, "IsGroupMember", 0) == 0) + { + mi.flags |= CMIF_GRAYED; + } + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) g_hContactMenuItems[CMI_LEAVE_GROUP], (LPARAM) &mi); + } + else if (chatType == 2) + { + // owning chat/group + mi.flags = CMIF_CHILDPOPUP; + mi.position= -2000006102; + mi.icolibItem = GetIconHandle("removeContactFromGroup"); + mi.pszName = GetIconDescription("removeContactFromGroup"); + mi.pszService = NULL; + g_hContactMenuItems[CMI_REMOVE_CONTACT_FROM_GROUP] = Menu_AddContactMenuItem(&mi); + + if (isOnline() && db_get_b(hContact, m_szModuleName, "IsGroupMember", 0) == 1) + { + map>::iterator groupsIt = this->isMemberByGroupContact.find(hContact); + if (groupsIt == this->isMemberByGroupContact.end()) + { + LOG("Group exists only on contact list"); + } + else + { + mi.hParentMenu = (HGENMENU) g_hContactMenuItems[CMI_REMOVE_CONTACT_FROM_GROUP]; + mi.flags = CMIF_ROOTHANDLE | CMIF_TCHAR; + + string fullSvcName; + string svcName = m_szModuleName; + svcName += "/RemoveContactFromGroup_"; + DBVARIANT dbv; + + for (map::iterator it = groupsIt->second.begin(); it != groupsIt->second.end(); ++it) + { + if (!db_get_s(it->first, m_szModuleName, "ID", &dbv, DBVT_ASCIIZ)) + { + fullSvcName = svcName + dbv.pszVal; + mi.pszService = (char*) fullSvcName.c_str(); + mi.ptszName = mir_a2t_cp(this->GetContactDisplayName(it->first).c_str(), CP_UTF8); + CreateServiceFunctionParam(mi.pszService, + GlobalServiceParam<&WhatsAppProto::OnRemoveContactFromGroup>, (LPARAM) it->first); + Menu_AddContactMenuItem(&mi); + db_free(&dbv); + mir_free(mi.ptszName); + } + } + } + mi.flags = CMIM_FLAGS; + } + else + { + mi.flags = CMIM_FLAGS | CMIF_GRAYED; + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) g_hContactMenuItems[CMI_REMOVE_CONTACT_FROM_GROUP], (LPARAM) &mi); + } + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) g_hContactMenuItems[CMI_REMOVE_GROUP], (LPARAM) &mi); + CallService(MS_CLIST_MODIFYMENUITEM, (WPARAM) g_hContactMenuItems[CMI_CHANGE_GROUP_SUBJECT], (LPARAM) &mi); + } + + return 0; } int WhatsAppProto::OnBuildStatusMenu(WPARAM wParam,LPARAM lParam) { - LOG(""); + LOG(""); char text[200]; strcpy(text,m_szModuleName); char *tDest = text+strlen(text); @@ -292,6 +292,6 @@ void WhatsAppProto::ToggleStatusMenuItems( BOOL bEnable ) CLISTMENUITEM clmi = {sizeof(clmi)}; clmi.flags = CMIM_FLAGS | (( bEnable ) ? 0 : CMIF_GRAYED); - CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM ) m_hMenuRoot, ( LPARAM )&clmi ); + CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM ) m_hMenuRoot, ( LPARAM )&clmi ); CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM ) m_hMenuCreateGroup, ( LPARAM )&clmi ); } diff --git a/protocols/WhatsApp/src/utils.cpp b/protocols/WhatsApp/src/utils.cpp index 96e8ee18f3..8444cdd6f1 100644 --- a/protocols/WhatsApp/src/utils.cpp +++ b/protocols/WhatsApp/src/utils.cpp @@ -2,22 +2,22 @@ void UnixTimeToFileTime(time_t t, LPFILETIME pft) { - // Note that LONGLONG is a 64-bit value - LONGLONG ll; + // Note that LONGLONG is a 64-bit value + LONGLONG ll; - ll = Int32x32To64(t, 10000000) + 116444736000000000; - pft->dwLowDateTime = (DWORD)ll; - pft->dwHighDateTime = ll >> 32; + ll = Int32x32To64(t, 10000000) + 116444736000000000; + pft->dwLowDateTime = (DWORD)ll; + pft->dwHighDateTime = ll >> 32; } DWORD utils::conversion::to_timestamp(std::string data) { DWORD timestamp = NULL; - /* + /* if (!utils::conversion::from_string(timestamp, data, std::dec)) { timestamp = static_cast(::time(NULL)); } - */ + */ return timestamp; } @@ -52,37 +52,37 @@ std::string utils::text::source_get_value(std::string* data, unsigned int argume std::string getLastErrorMsg() { - // Retrieve the system error message for the last-error code + // Retrieve the system error message for the last-error code - LPVOID lpMsgBuf; - DWORD dw = WSAGetLastError(); + LPVOID lpMsgBuf; + DWORD dw = WSAGetLastError(); - FormatMessageA( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - dw, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR) &lpMsgBuf, - 0, NULL ); + FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + dw, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR) &lpMsgBuf, + 0, NULL ); - // Display the error message and exit the process - /* - lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, - (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); - StringCchPrintf((LPTSTR)lpDisplayBuf, - LocalSize(lpDisplayBuf) / sizeof(TCHAR), - TEXT("%s"), - lpMsgBuf); - */ + // Display the error message and exit the process + /* + lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, + (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); + StringCchPrintf((LPTSTR)lpDisplayBuf, + LocalSize(lpDisplayBuf) / sizeof(TCHAR), + TEXT("%s"), + lpMsgBuf); + */ - std::string ret((LPSTR) lpMsgBuf); - LocalFree(lpMsgBuf); - //LocalFree(lpDisplayBuf); + std::string ret((LPSTR) lpMsgBuf); + LocalFree(lpMsgBuf); + //LocalFree(lpDisplayBuf); - //return std::string((LPCTSTR)lpDisplayBuf); - return ret; + //return std::string((LPCTSTR)lpDisplayBuf); + return ret; } int utils::debug::log(std::string file_name, std::string text) -- cgit v1.2.3