From de6c7df3c362fa0104e7d908c29614266caaa9d6 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Mon, 26 Jan 2015 16:19:13 +0000 Subject: fixed user search & addition git-svn-id: http://svn.miranda-ng.org/main/trunk@11918 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- .../WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp | 30 ++++----- .../WhatsApp/src/WhatsAPI++/ProtocolTreeNode.cpp | 26 ++++---- protocols/WhatsApp/src/WhatsAPI++/WALogin.cpp | 44 +++++++------- protocols/WhatsApp/src/WhatsAPI++/WALogin.h | 4 +- protocols/WhatsApp/src/chat.cpp | 4 +- protocols/WhatsApp/src/connection.cpp | 28 ++++----- protocols/WhatsApp/src/contacts.cpp | 49 ++++++--------- protocols/WhatsApp/src/dialogs.cpp | 16 ++--- protocols/WhatsApp/src/messages.cpp | 12 ++-- protocols/WhatsApp/src/proto.cpp | 71 +++++++++++++++++----- protocols/WhatsApp/src/proto.h | 55 ++++++++++------- protocols/WhatsApp/src/utils.cpp | 5 ++ 12 files changed, 195 insertions(+), 149 deletions(-) diff --git a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp index 99c186f126..0cb12b2e93 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp @@ -183,25 +183,25 @@ ReadData* BinTreeNodeReader::readString(int token) } return ret; - case 255: - bSize = readInt8(this->in); - { - int size = bSize & 0x7f; - int numnibbles = size * 2 - ((bSize & 0x80) ? 1 : 0); - + case 255: + bSize = readInt8(this->in); + { + int size = bSize & 0x7f; + int numnibbles = size * 2 - ((bSize & 0x80) ? 1 : 0); + std::vector tmp(size); fillArray(tmp, size, this->in); - std::string s; - for (int i = 0; i < numnibbles; i++) { - char c = (tmp[i / 2] >> (4 - ((i & 1) << 2))) & 0xF; - if (c < 10) s += (c + '0'); - else s += (c - 10 + '-'); - } - + std::string s; + for (int i = 0; i < numnibbles; i++) { + char c = (tmp[i / 2] >> (4 - ((i & 1) << 2))) & 0xF; + if (c < 10) s += (c + '0'); + else s += (c - 10 + '-'); + } + ret->type = STRING; ret->data = new std::string(s); - } - return ret; + } + return ret; case 250: std::string* user = readStringAsString(); diff --git a/protocols/WhatsApp/src/WhatsAPI++/ProtocolTreeNode.cpp b/protocols/WhatsApp/src/WhatsAPI++/ProtocolTreeNode.cpp index cb3bc19258..7ef362ef4b 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/ProtocolTreeNode.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/ProtocolTreeNode.cpp @@ -12,35 +12,35 @@ static std::string nilstr; -ProtocolTreeNode::ProtocolTreeNode(const string& tag, vector* data, vector *children) +ProtocolTreeNode::ProtocolTreeNode(const string &_tag, vector* _data, vector *_children) : + tag(_tag) { - this->tag = tag; - this->data = data; - this->attributes = NULL; - this->children = children; + data = _data; + attributes = NULL; + children = _children; } -ProtocolTreeNode::ProtocolTreeNode(const string& tag, ProtocolTreeNode* child) +ProtocolTreeNode::ProtocolTreeNode(const string &_tag, ProtocolTreeNode *_child) : + tag(_tag) { - this->tag = tag; this->data = NULL; this->attributes = NULL; - this->children = new std::vector(1); - (*this->children)[0] = child; + this->children = new std::vector(); + children->push_back(_child); } ProtocolTreeNode::~ProtocolTreeNode() { - if (this->attributes != NULL) - delete this->attributes; + delete this->attributes; + if (this->children != NULL) { for (size_t i = 0; i < this->children->size(); i++) if (this->children->at(i) != NULL) delete this->children->at(i); delete this->children; } - if (this->data != NULL) - delete data; + + delete data; } diff --git a/protocols/WhatsApp/src/WhatsAPI++/WALogin.cpp b/protocols/WhatsApp/src/WhatsAPI++/WALogin.cpp index 40471ae559..dd29850885 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/WALogin.cpp +++ b/protocols/WhatsApp/src/WhatsAPI++/WALogin.cpp @@ -22,7 +22,7 @@ const std::string WALogin::NONCE_KEY = "nonce=\""; WALogin::WALogin(WAConnection* connection, const std::string& password) { - this->connection = connection; + m_pConnection = connection; this->password = password; this->account_kind = -1; this->expire_date = 0L; @@ -30,21 +30,21 @@ WALogin::WALogin(WAConnection* connection, const std::string& password) std::vector* WALogin::login(const std::vector& authBlob) { - connection->out->streamStart(connection->domain, connection->resource); + m_pConnection->out->streamStart(m_pConnection->domain, m_pConnection->resource); - connection->logData("sent stream start"); + m_pConnection->logData("sent stream start"); sendFeatures(); - connection->logData("sent features"); + m_pConnection->logData("sent features"); sendAuth(authBlob); - connection->logData("send auth, auth blob size %d", authBlob.size()); + m_pConnection->logData("send auth, auth blob size %d", authBlob.size()); - connection->in->streamStart(); + m_pConnection->in->streamStart(); - connection->logData("read stream start"); + m_pConnection->logData("read stream start"); return this->readFeaturesUntilChallengeOrSuccess(); } @@ -52,7 +52,7 @@ std::vector* WALogin::login(const std::vector& aut void WALogin::sendResponse(const std::vector& challengeData) { std::vector* authBlob = this->getAuthBlob(challengeData); - connection->out->write(ProtocolTreeNode("response", authBlob)); + m_pConnection->out->write(ProtocolTreeNode("response", authBlob)); } void WALogin::sendFeatures() @@ -64,7 +64,7 @@ void WALogin::sendFeatures() ProtocolTreeNode* pictureChild = new ProtocolTreeNode("w:profile:picture") << XATTR("type", "all"); children->push_back(pictureChild); - connection->out->write(ProtocolTreeNode("stream:features", NULL, children), true); + m_pConnection->out->write(ProtocolTreeNode("stream:features", NULL, children), true); } void WALogin::sendAuth(const std::vector& existingChallenge) @@ -73,8 +73,8 @@ void WALogin::sendAuth(const std::vector& existingChallenge) if (!existingChallenge.empty()) data = this->getAuthBlob(existingChallenge); - connection->out->write(ProtocolTreeNode("auth", data) << - XATTR("mechanism", "WAUTH-2") << XATTR("user", connection->user), true); + m_pConnection->out->write(ProtocolTreeNode("auth", data) << + XATTR("mechanism", "WAUTH-2") << XATTR("user", m_pConnection->user), true); } std::vector* WALogin::getAuthBlob(const std::vector& nonce) @@ -82,31 +82,31 @@ std::vector* WALogin::getAuthBlob(const std::vectorpassword, nonce, out); - this->connection->inputKey.init(out + 40, out + 60); - this->connection->outputKey.init(out, out + 20); + m_pConnection->inputKey.init(out + 40, out + 60); + m_pConnection->outputKey.init(out, out + 20); std::vector* list = new std::vector(0); for (int i = 0; i < 4; i++) list->push_back(0); - list->insert(list->end(), connection->user.begin(), connection->user.end()); + list->insert(list->end(), m_pConnection->user.begin(), m_pConnection->user.end()); list->insert(list->end(), nonce.begin(), nonce.end()); - this->connection->outputKey.encodeMessage(&((*list)[0]), 0, 4, (int)list->size() - 4); + m_pConnection->outputKey.encodeMessage(&((*list)[0]), 0, 4, (int)list->size() - 4); return list; } std::vector* WALogin::readFeaturesUntilChallengeOrSuccess() { - while (ProtocolTreeNode *root = connection->in->nextTree()) { + while (ProtocolTreeNode *root = m_pConnection->in->nextTree()) { #ifdef _DEBUG { string tmp = root->toString(); - connection->logData(tmp.c_str()); + m_pConnection->logData(tmp.c_str()); } #endif if (ProtocolTreeNode::tagEquals(root, "stream:features")) { - connection->supports_receipt_acks = root->getChild("receipt_acks") != NULL; + m_pConnection->supports_receipt_acks = root->getChild("receipt_acks") != NULL; delete root; continue; } @@ -114,9 +114,9 @@ std::vector* WALogin::readFeaturesUntilChallengeOrSuccess() std::vector challengedata(root->data->begin(), root->data->end()); delete root; this->sendResponse(challengedata); - connection->logData("Send response"); + m_pConnection->logData("Send response"); std::vector data = this->readSuccess(); - connection->logData("Read success"); + m_pConnection->logData("Read success"); return new std::vector(data.begin(), data.end()); } if (ProtocolTreeNode::tagEquals(root, "success")) { @@ -131,7 +131,7 @@ std::vector* WALogin::readFeaturesUntilChallengeOrSuccess() void WALogin::parseSuccessNode(ProtocolTreeNode* node) { - connection->out->setSecure(); + m_pConnection->out->setSecure(); const string &expiration = node->getAttributeValue("expiration"); if (!expiration.empty()) { @@ -151,7 +151,7 @@ void WALogin::parseSuccessNode(ProtocolTreeNode* node) std::vector WALogin::readSuccess() { - ProtocolTreeNode *node = connection->in->nextTree(); + ProtocolTreeNode *node = m_pConnection->in->nextTree(); if (ProtocolTreeNode::tagEquals(node, "failure")) { delete node; diff --git a/protocols/WhatsApp/src/WhatsAPI++/WALogin.h b/protocols/WhatsApp/src/WhatsAPI++/WALogin.h index 440f34f71b..05e654549e 100644 --- a/protocols/WhatsApp/src/WhatsAPI++/WALogin.h +++ b/protocols/WhatsApp/src/WhatsAPI++/WALogin.h @@ -25,7 +25,7 @@ private: RC4_KEY rc4; unsigned char key[20], keyMac[20]; int seq; - HMAC_CTX hmac; + HMAC_CTX hmac; void hmacsha1(unsigned char* text, int textLength, unsigned char *out); @@ -44,7 +44,7 @@ public: class WALogin { private: static const std::string NONCE_KEY; - WAConnection *connection; + WAConnection *m_pConnection; std::vector* getAuthBlob(const std::vector& nonce); void sendResponse(const std::vector& challengeData); diff --git a/protocols/WhatsApp/src/chat.cpp b/protocols/WhatsApp/src/chat.cpp index d06e8f357e..790906cb8f 100644 --- a/protocols/WhatsApp/src/chat.cpp +++ b/protocols/WhatsApp/src/chat.cpp @@ -16,7 +16,6 @@ int WhatsAppProto::OnChatOutgoing(WPARAM wParam, LPARAM lParam) { GCHOOK *hook = reinterpret_cast(lParam); char *text; - char *id; if (strcmp(hook->pDest->pszModule, m_szModuleName)) return 0; @@ -27,7 +26,7 @@ int WhatsAppProto::OnChatOutgoing(WPARAM wParam, LPARAM lParam) { std::string msg = text; - id = mir_t2a_cp(hook->pDest->ptszID, CP_UTF8); + char *id = mir_t2a_cp(hook->pDest->ptszID, CP_UTF8); std::string chat_id = id; mir_free(text); @@ -65,4 +64,3 @@ int WhatsAppProto::OnChatOutgoing(WPARAM wParam, LPARAM lParam) return 0; } - diff --git a/protocols/WhatsApp/src/connection.cpp b/protocols/WhatsApp/src/connection.cpp index af7ca81d6e..d911bc31a4 100644 --- a/protocols/WhatsApp/src/connection.cpp +++ b/protocols/WhatsApp/src/connection.cpp @@ -52,9 +52,9 @@ void WhatsAppProto::stayConnectedLoop(void*) this->conn = NULL; while (true) { - if (connection != NULL) { - delete connection; - connection = NULL; + if (m_pConnection != NULL) { + delete m_pConnection; + m_pConnection = NULL; } if (this->conn != NULL) { delete this->conn; @@ -85,20 +85,20 @@ void WhatsAppProto::stayConnectedLoop(void*) portNumber = 5222, resource += "-5222"; this->conn = new WASocketConnection("c.whatsapp.net", portNumber); - this->connection = new WAConnection(this->phoneNumber, resource, &this->connMutex, this, this); - this->connection->init(&writerMutex, this->conn); + m_pConnection = new WAConnection(this->phoneNumber, resource, &this->connMutex, this, this); + m_pConnection->init(&writerMutex, this->conn); { - WALogin login(connection, password); + WALogin login(m_pConnection, password); std::vector *nextChallenge = login.login(*this->challenge); delete this->challenge; this->challenge = nextChallenge; - connection->setLogin(&login); + m_pConnection->setLogin(&login); } - connection->nick = this->nick; - connection->setVerboseId(true); + m_pConnection->nick = this->nick; + m_pConnection->setVerboseId(true); if (desiredStatus != ID_STATUS_INVISIBLE) - connection->sendAvailableForChat(); + m_pConnection->sendAvailableForChat(); debugLogA("Set status to online"); this->m_iStatus = desiredStatus; @@ -110,7 +110,7 @@ void WhatsAppProto::stayConnectedLoop(void*) // #TODO Move out of try block. Exception is expected on disconnect while (true) { this->lastPongTime = time(NULL); - if (!connection->read()) + if (!m_pConnection->read()) break; } debugLogA("Exit from read-loop"); @@ -136,14 +136,14 @@ 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) { + if (this->m_iStatus != ID_STATUS_OFFLINE && m_pConnection != 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) { try { debugLogA("send ping"); this->lastPongTime = time(NULL); - this->connection->sendPing(); + m_pConnection->sendPing(); } catch (exception &e) { debugLogA("Exception: %s", e.what()); @@ -162,7 +162,7 @@ void WhatsAppProto::onPing(const std::string& id) if (this->isOnline()) { try { debugLogA("Sending pong with id %s", id.c_str()); - this->connection->sendPong(id); + m_pConnection->sendPong(id); } CODE_BLOCK_CATCH_ALL } diff --git a/protocols/WhatsApp/src/contacts.cpp b/protocols/WhatsApp/src/contacts.cpp index d9db3e0d43..271c038622 100644 --- a/protocols/WhatsApp/src/contacts.cpp +++ b/protocols/WhatsApp/src/contacts.cpp @@ -13,7 +13,7 @@ bool WhatsAppProto::IsMyContact(MCONTACT hContact, bool include_chat) return false; } -MCONTACT WhatsAppProto::AddToContactList(const std::string& jid, BYTE type, bool dont_check, const char *new_name, bool isChatRoom, bool isHidden) +MCONTACT WhatsAppProto::AddToContactList(const std::string& jid, BYTE , bool dont_check, const char *new_name, bool isChatRoom, bool isHidden) { if (!dont_check) { // First, check if this contact exists @@ -134,8 +134,8 @@ void WhatsAppProto::ProcessBuddyList(void*) } if (getByte(hContact, "SimpleChatRoom", 0) == 0) { - this->connection->sendQueryLastOnline((char*)jid); - this->connection->sendPresenceSubscriptionRequest((char*)jid); + m_pConnection->sendQueryLastOnline((char*)jid); + m_pConnection->sendPresenceSubscriptionRequest((char*)jid); } } CODE_BLOCK_CATCH_ALL @@ -144,30 +144,17 @@ void WhatsAppProto::ProcessBuddyList(void*) if (jids.size() > 0) { try { - this->connection->sendGetPictureIds(jids); + m_pConnection->sendGetPictureIds(jids); } CODE_BLOCK_CATCH_ALL } try { - this->connection->sendGetGroups(); - this->connection->sendGetOwningGroups(); + m_pConnection->sendGetGroups(); + m_pConnection->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"); - - this->connection->sendQueryLastOnline(jid.c_str()); - this->connection->sendPresenceSubscriptionRequest(jid.c_str()); - - mir_free(targ); - mir_free(id); -} - void WhatsAppProto::onAvailable(const std::string& paramString, bool paramBoolean) { MCONTACT hContact = this->AddToContactList(paramString, 0, false); @@ -218,7 +205,7 @@ void WhatsAppProto::onPictureChanged(const std::string& from, const std::string& if (this->isOnline()) { vector ids; ids.push_back(from); - this->connection->sendGetPictureIds(ids); + m_pConnection->sendGetPictureIds(ids); } } @@ -271,7 +258,7 @@ void WhatsAppProto::onSendGetPictureIds(std::map* ids) if (it->second.size() > 0 && it->second.compare(oldId) != 0) { try { - this->connection->sendGetPicture(it->first, "image", oldId, it->second); + m_pConnection->sendGetPicture(it->first, "image", oldId, it->second); } CODE_BLOCK_CATCH_ALL } @@ -290,7 +277,7 @@ TCHAR* WhatsAppProto::GetContactDisplayName(const string& jid) void WhatsAppProto::SendGetGroupInfoWorker(void* data) { if (this->isOnline()) - this->connection->sendGetGroupInfo(*((std::string*) data)); + m_pConnection->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) @@ -303,7 +290,7 @@ void WhatsAppProto::onGroupInfo(const std::string& gjid, const std::string& owne } setByte(hContact, "SimpleChatRoom", ownerJid.compare(this->jid) == 0 ? 2 : 1); if (this->isOnline()) - this->connection->sendGetParticipants(gjid); + m_pConnection->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) @@ -333,7 +320,7 @@ void WhatsAppProto::onGroupAddUser(const std::string& paramString1, const std::s } if (this->isOnline()) - this->connection->sendGetGroupInfo(paramString1); + m_pConnection->sendGetGroupInfo(paramString1); } void WhatsAppProto::onGroupRemoveUser(const std::string ¶mString1, const std::string ¶mString2) @@ -355,7 +342,7 @@ void WhatsAppProto::onGroupRemoveUser(const std::string ¶mString1, const std CMString tmp(FORMAT, TranslateT("User '%s' has been removed from the group"), this->GetContactDisplayName(paramString2)); this->NotifyEvent(ptszGroupName, tmp, hContact, WHATSAPP_EVENT_OTHER); - this->connection->sendGetGroupInfo(paramString1); + m_pConnection->sendGetGroupInfo(paramString1); } } @@ -435,7 +422,7 @@ INT_PTR __cdecl WhatsAppProto::OnAddContactToGroup(WPARAM wParam, LPARAM, LPARAM if (getString((MCONTACT)lParam, "ID", &dbv)) return NULL; - this->connection->sendAddParticipants(string(dbv.pszVal), participants); + m_pConnection->sendAddParticipants(string(dbv.pszVal), participants); db_free(&dbv); return NULL; @@ -462,7 +449,7 @@ INT_PTR __cdecl WhatsAppProto::OnRemoveContactFromGroup(WPARAM wParam, LPARAM, L if (getString((MCONTACT)wParam, "ID", &dbv)) return NULL; - this->connection->sendRemoveParticipants(string(dbv.pszVal), participants); + m_pConnection->sendRemoveParticipants(string(dbv.pszVal), participants); db_free(&dbv); return NULL; @@ -491,7 +478,7 @@ void WhatsAppProto::HandleReceiveGroups(const std::vector& groups, bool if (isOwned) { this->isMemberByGroupContact[hContact]; // []-operator creates entry, if it doesn't exist setByte(hContact, "SimpleChatRoom", 2); - this->connection->sendGetParticipants(*it); + m_pConnection->sendGetParticipants(*it); } else isMember[hContact] = true; } @@ -535,7 +522,7 @@ void __cdecl WhatsAppProto::SendSetGroupNameWorker(void* data) ptrA jid(getStringA(*((MCONTACT*)ibr->userData), WHATSAPP_KEY_ID)); if (jid && this->isOnline()) - this->connection->sendSetNewSubject((char*)jid, groupName); + m_pConnection->sendSetNewSubject((char*)jid, groupName); delete ibr->userData; delete ibr; @@ -547,7 +534,7 @@ void __cdecl WhatsAppProto::SendCreateGroupWorker(void* data) string groupName(ibr->value); mir_free(ibr->value); if (this->isOnline()) - this->connection->sendCreateGroupChat(groupName); + m_pConnection->sendCreateGroupChat(groupName); } INT_PTR __cdecl WhatsAppProto::OnChangeGroupSubject(WPARAM hContact, LPARAM lParam) @@ -579,7 +566,7 @@ INT_PTR __cdecl WhatsAppProto::OnLeaveGroup(WPARAM hContact, LPARAM) ptrA jid(getStringA(hContact, WHATSAPP_KEY_ID)); if (jid && this->isOnline()) { setByte(hContact, "IsGroupMember", 0); - this->connection->sendLeaveGroup((char*)jid); + m_pConnection->sendLeaveGroup((char*)jid); } return 0; } diff --git a/protocols/WhatsApp/src/dialogs.cpp b/protocols/WhatsApp/src/dialogs.cpp index d831bd7844..e00b69196e 100644 --- a/protocols/WhatsApp/src/dialogs.cpp +++ b/protocols/WhatsApp/src/dialogs.cpp @@ -15,20 +15,20 @@ INT_PTR CALLBACK WhatsAppAccountProc(HWND hwndDlg, UINT message, WPARAM wparam, SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lparam); SendDlgItemMessage(hwndDlg, IDC_PW, EM_LIMITTEXT, 3, 0); SendDlgItemMessage(hwndDlg, IDC_PW2, EM_LIMITTEXT, 3, 0); - CheckDlgButton(hwndDlg, IDC_SSL, db_get_b(NULL, proto->ModuleName(), WHATSAPP_KEY_SSL, 0) ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(hwndDlg, IDC_SSL, db_get_b(NULL, proto->m_szModuleName, WHATSAPP_KEY_SSL, 0) ? BST_CHECKED : BST_UNCHECKED); DBVARIANT dbv; - if (!db_get_s(0, proto->ModuleName(), WHATSAPP_KEY_CC, &dbv, DBVT_ASCIIZ)) { + if (!db_get_s(0, proto->m_szModuleName, WHATSAPP_KEY_CC, &dbv, DBVT_ASCIIZ)) { SetDlgItemTextA(hwndDlg, IDC_CC, dbv.pszVal); db_free(&dbv); } - if (!db_get_s(0, proto->ModuleName(), WHATSAPP_KEY_LOGIN, &dbv, DBVT_ASCIIZ)) { + if (!db_get_s(0, proto->m_szModuleName, WHATSAPP_KEY_LOGIN, &dbv, DBVT_ASCIIZ)) { SetDlgItemTextA(hwndDlg, IDC_LOGIN, dbv.pszVal); db_free(&dbv); } - if (!db_get_s(0, proto->ModuleName(), WHATSAPP_KEY_NICK, &dbv, DBVT_ASCIIZ)) { + if (!db_get_s(0, proto->m_szModuleName, WHATSAPP_KEY_NICK, &dbv, DBVT_ASCIIZ)) { SetDlgItemTextA(hwndDlg, IDC_NICK, dbv.pszVal); db_free(&dbv); } @@ -108,15 +108,15 @@ INT_PTR CALLBACK WhatsAppAccountProc(HWND hwndDlg, UINT message, WPARAM wparam, char str[128]; GetDlgItemTextA(hwndDlg, IDC_CC, str, SIZEOF(str)); - db_set_s(0, proto->ModuleName(), WHATSAPP_KEY_CC, str); + db_set_s(0, proto->m_szModuleName, WHATSAPP_KEY_CC, str); GetDlgItemTextA(hwndDlg, IDC_LOGIN, str, SIZEOF(str)); - db_set_s(0, proto->ModuleName(), WHATSAPP_KEY_LOGIN, str); + db_set_s(0, proto->m_szModuleName, WHATSAPP_KEY_LOGIN, str); GetDlgItemTextA(hwndDlg, IDC_NICK, str, SIZEOF(str)); - db_set_s(0, proto->ModuleName(), WHATSAPP_KEY_NICK, str); + db_set_s(0, proto->m_szModuleName, WHATSAPP_KEY_NICK, str); - db_set_b(0, proto->ModuleName(), WHATSAPP_KEY_SSL, IsDlgButtonChecked(hwndDlg, IDC_SSL)); + db_set_b(0, proto->m_szModuleName, WHATSAPP_KEY_SSL, IsDlgButtonChecked(hwndDlg, IDC_SSL)); return TRUE; } break; diff --git a/protocols/WhatsApp/src/messages.cpp b/protocols/WhatsApp/src/messages.cpp index 3526daafe9..d86f5c017d 100644 --- a/protocols/WhatsApp/src/messages.cpp +++ b/protocols/WhatsApp/src/messages.cpp @@ -35,7 +35,7 @@ void WhatsAppProto::onMessageForMe(FMessage* paramFMessage, bool paramBoolean) recv.timestamp = paramFMessage->timestamp; //time(NULL); ProtoChainRecvMsg(hContact, &recv); - this->connection->sendMessageReceived(paramFMessage); + m_pConnection->sendMessageReceived(paramFMessage); } int WhatsAppProto::SendMsg(MCONTACT hContact, int flags, const char *msg) @@ -59,7 +59,7 @@ void WhatsAppProto::SendMsgWorker(void* p) ProtoBroadcastAck(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 (!getString(data->hContact, "ID", &dbv) && this->connection != NULL) { + else if (!getString(data->hContact, "ID", &dbv) && m_pConnection != NULL) { try { setDword(data->hContact, WHATSAPP_KEY_LAST_MSG_STATE, 2); setDword(data->hContact, WHATSAPP_KEY_LAST_MSG_ID_HEADER, this->msgIdHeader); @@ -74,7 +74,7 @@ void WhatsAppProto::SendMsgWorker(void* p) db_free(&dbv); - this->connection->sendMessage(&fmsg); + m_pConnection->sendMessage(&fmsg); } catch (exception &e) { debugLogA("exception: %s", e.what()); @@ -103,7 +103,7 @@ void WhatsAppProto::RecvMsgWorker(void *p) //WAConnection.cpp l1225 - message will be deleted. We cannot send the ack inside a thread! //FMessage *fmsg = static_cast(p); - //this->connection->sendMessageReceived(fmsg); + //m_pConnection->sendMessageReceived(fmsg); //delete fmsg; } @@ -139,9 +139,9 @@ void WhatsAppProto::SendTypingWorker(void* p) ptrA jid(getStringA(typing->hContact, WHATSAPP_KEY_ID)); if (jid && this->isOnline()) { if (typing->status == PROTOTYPE_SELFTYPING_ON) - this->connection->sendComposing((char*)jid); + m_pConnection->sendComposing((char*)jid); else - this->connection->sendPaused((char*)jid); + m_pConnection->sendPaused((char*)jid); } delete typing; diff --git a/protocols/WhatsApp/src/proto.cpp b/protocols/WhatsApp/src/proto.cpp index e889854871..10b933b955 100644 --- a/protocols/WhatsApp/src/proto.cpp +++ b/protocols/WhatsApp/src/proto.cpp @@ -2,6 +2,16 @@ #include "WhatsAPI++\WARegister.h" +struct SearchParam +{ + SearchParam(const TCHAR *_jid, LONG _id) : + jid(_jid), id(_id) + {} + + std::tstring jid; + LONG id; +}; + WhatsAppProto::WhatsAppProto(const char* proto_name, const TCHAR* username) : PROTO(proto_name, username) { @@ -128,14 +138,14 @@ int WhatsAppProto::SetStatus(int new_status) ForkThread(&WhatsAppProto::sentinelLoop, this); ForkThread(&WhatsAppProto::stayConnectedLoop, this); } - else if (this->connection != NULL) { + else if (m_pConnection != NULL) { if (m_iDesiredStatus == ID_STATUS_ONLINE) { - this->connection->sendAvailableForChat(); + m_pConnection->sendAvailableForChat(); m_iStatus = ID_STATUS_ONLINE; ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus); } else if (m_iStatus == ID_STATUS_ONLINE && m_iDesiredStatus == ID_STATUS_INVISIBLE) { - this->connection->sendClose(); + m_pConnection->sendClose(); m_iStatus = ID_STATUS_INVISIBLE; SetAllContactStatuses(ID_STATUS_OFFLINE, true); ProtoBroadcastAck(0, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, m_iStatus); @@ -148,12 +158,25 @@ int WhatsAppProto::SetStatus(int new_status) MCONTACT WhatsAppProto::AddToList(int flags, PROTOSEARCHRESULT* psr) { - return NULL; + if (psr->id == NULL) + return NULL; + + std::string phone(ptrA(mir_utf8encodeT(psr->id))); + std::string jid(phone + "@s.whatsapp.net"); + + MCONTACT hContact = AddToContactList(jid, 0, false, phone.c_str()); + if (!(flags & PALF_TEMPORARY)) + db_unset(hContact, "CList", "NotOnList"); + + m_pConnection->sendQueryLastOnline(jid.c_str()); + m_pConnection->sendPresenceSubscriptionRequest(jid.c_str()); + return hContact; } int WhatsAppProto::AuthRequest(MCONTACT hContact, const PROTOCHAR *message) { - return this->RequestFriendship((WPARAM)hContact, NULL); + RequestFriendship(hContact); + return 0; } int WhatsAppProto::Authorize(MEVENT hDbEvent) @@ -161,14 +184,36 @@ int WhatsAppProto::Authorize(MEVENT hDbEvent) return 1; } +///////////////////////////////////////////////////////////////////////////////////////// + +void WhatsAppProto::SearchAckThread(void *targ) +{ + Sleep(100); + + SearchParam *param = (SearchParam*)targ; + PROTOSEARCHRESULT sr = { 0 }; + sr.cbSize = sizeof(sr); + sr.flags = PSR_TCHAR; + sr.nick = _T(""); + sr.firstName = _T(""); + sr.lastName = _T(""); + sr.id = (TCHAR*)param->jid.c_str(); + + ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)param->id, (LPARAM)&sr); + ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)param->id, 0); + + delete param; +} + HANDLE WhatsAppProto::SearchBasic(const PROTOCHAR* id) { if (isOffline()) return 0; - TCHAR* email = mir_tstrdup(id); - ForkThread(&WhatsAppProto::SearchAckThread, email); - return email; + // fake - we always accept search + SearchParam *param = new SearchParam(id, GetSerial()); + ForkThread(&WhatsAppProto::SearchAckThread, param); + return (HANDLE)param->id; } ///////////////////////////////////////////////////////////////////////////////////////// @@ -298,18 +343,16 @@ int WhatsAppProto::OnOptionsInit(WPARAM wParam, LPARAM lParam) return 0; } -int WhatsAppProto::RequestFriendship(WPARAM hContact, LPARAM lParam) +void WhatsAppProto::RequestFriendship(MCONTACT hContact) { if (hContact == NULL || isOffline()) - return 0; + return; ptrA jid(getStringA(hContact, WHATSAPP_KEY_ID)); if (jid) { - this->connection->sendQueryLastOnline((char*)jid); - this->connection->sendPresenceSubscriptionRequest((char*)jid); + m_pConnection->sendQueryLastOnline((char*)jid); + m_pConnection->sendPresenceSubscriptionRequest((char*)jid); } - - return 0; } std::tstring WhatsAppProto::GetAvatarFolder() diff --git a/protocols/WhatsApp/src/proto.h b/protocols/WhatsApp/src/proto.h index 099e89de03..44dde4958b 100644 --- a/protocols/WhatsApp/src/proto.h +++ b/protocols/WhatsApp/src/proto.h @@ -9,28 +9,19 @@ public: WhatsAppProto(const char *proto_name, const TCHAR *username); ~WhatsAppProto( ); - inline const char* ModuleName() const - { - return m_szModuleName; + inline bool isOnline() const + { return (m_pConnection != NULL); } - inline bool isOnline() - { - return (m_iStatus != ID_STATUS_OFFLINE && m_iStatus != ID_STATUS_CONNECTING && - connection != NULL); - } - - inline bool isOffline() - { - return (m_iStatus == ID_STATUS_OFFLINE); + inline bool isOffline() const + { return (m_iStatus == ID_STATUS_OFFLINE); } - inline bool isInvisible() - { - return (m_iStatus == ID_STATUS_INVISIBLE); + inline bool isInvisible() const + { return (m_iStatus == ID_STATUS_INVISIBLE); } - //PROTO_INTERFACE + // PROTO_INTERFACE virtual MCONTACT __cdecl AddToList(int flags, PROTOSEARCHRESULT* psr); virtual MCONTACT __cdecl AddToListByEvent(int flags, int iContact, MEVENT hDbEvent) { return NULL; } @@ -76,9 +67,9 @@ public: virtual int __cdecl OnEvent(PROTOEVENTTYPE iEventType, WPARAM wParam, LPARAM lParam) { return 1; } - //////////////////////// - + ////////////////////////////////////////////////////////////////////////////////////// // Services + INT_PTR __cdecl SvcCreateAccMgrUI(WPARAM, LPARAM); INT_PTR __cdecl OnJoinChat(WPARAM, LPARAM); INT_PTR __cdecl OnLeaveChat(WPARAM, LPARAM); @@ -86,9 +77,9 @@ public: int __cdecl OnOptionsInit(WPARAM, LPARAM); int __cdecl OnModulesLoaded(WPARAM, LPARAM); - int __cdecl RequestFriendship(WPARAM, LPARAM); - + ////////////////////////////////////////////////////////////////////////////////////// // Events + int __cdecl OnBuildStatusMenu(WPARAM, LPARAM); int __cdecl OnChatOutgoing(WPARAM, LPARAM); int __cdecl OnPrebuildContactMenu(WPARAM, LPARAM); @@ -103,11 +94,15 @@ public: void __cdecl stayConnectedLoop(void*); void __cdecl sentinelLoop(void*); + ////////////////////////////////////////////////////////////////////////////////////// // Processing Threads + void __cdecl ProcessBuddyList(void*); void __cdecl SearchAckThread(void*); + ////////////////////////////////////////////////////////////////////////////////////// // Worker Threads + void __cdecl SendMsgWorker(void*); void __cdecl RecvMsgWorker(void*); void __cdecl SendTypingWorker(void*); @@ -115,7 +110,9 @@ public: void __cdecl SendSetGroupNameWorker(void*); void __cdecl SendCreateGroupWorker(void*); + ////////////////////////////////////////////////////////////////////////////////////// // Contacts handling + MCONTACT AddToContactList(const std::string &jid, BYTE type = 0, bool dont_check = false, const char *new_name = NULL, bool isChatRoom = false, bool isHidden = false); bool IsMyContact(MCONTACT hContact, bool include_chat = false); @@ -125,20 +122,28 @@ public: TCHAR* GetContactDisplayName(const string &jid); void InitContactMenus(); void HandleReceiveGroups(const std::vector &groups, bool isOwned); + void RequestFriendship(MCONTACT hContact); bool IsGroupChat(MCONTACT hC, bool checkIsAdmin = false) { return getByte(hC, "SimpleChatRoom", 0) > (checkIsAdmin ? 1 : 0); } + ////////////////////////////////////////////////////////////////////////////////////// // Registration + bool Register(int state, const string &cc, const string &number, const string &code, string &password); + ////////////////////////////////////////////////////////////////////////////////////// // Helpers + std::tstring GetAvatarFolder(); void ToggleStatusMenuItems(BOOL bEnable); + LONG GetSerial(void); + ////////////////////////////////////////////////////////////////////////////////////// // Handles, Locks + HGENMENU m_hMenuRoot; HANDLE m_hMenuCreateGroup; @@ -149,7 +154,7 @@ public: std::tstring def_avatar_folder_; WASocketConnection* conn; - WAConnection* connection; + WAConnection* m_pConnection; Mutex connMutex; int lastPongTime; @@ -162,7 +167,13 @@ public: std::map hContactByJid; map> isMemberByGroupContact; +private: + LONG m_serial; + + ////////////////////////////////////////////////////////////////////////////////////// // WhatsApp Events + +protected: virtual void onMessageForMe(FMessage* paramFMessage, bool paramBoolean); virtual void onMessageStatusUpdate(FMessage* paramFMessage); virtual void onMessageError(FMessage* message, int paramInt) { ; } @@ -198,7 +209,9 @@ public: virtual void onParticipatingGroups(const std::vector& paramVector); virtual void onLeaveGroup(const std::string& paramString); + ////////////////////////////////////////////////////////////////////////////////////// // Information providing + void NotifyEvent(const TCHAR *title, const TCHAR *info, MCONTACT contact, DWORD flags, TCHAR *url = NULL); void NotifyEvent(const std::string &title, const std::string &info, MCONTACT contact, DWORD flags, TCHAR *url = NULL); }; diff --git a/protocols/WhatsApp/src/utils.cpp b/protocols/WhatsApp/src/utils.cpp index 0aa95f1a16..0155ba2206 100644 --- a/protocols/WhatsApp/src/utils.cpp +++ b/protocols/WhatsApp/src/utils.cpp @@ -1,5 +1,10 @@ #include "common.h" +LONG WhatsAppProto::GetSerial(void) +{ + return ::InterlockedIncrement(&m_serial); +} + std::string getLastErrorMsg() { // Retrieve the system error message for the last-error code -- cgit v1.2.3