diff options
Diffstat (limited to 'protocols/WhatsApp')
-rw-r--r-- | protocols/WhatsApp/src/WhatsAPI++/BinTreeNodeReader.cpp | 30 | ||||
-rw-r--r-- | protocols/WhatsApp/src/WhatsAPI++/ProtocolTreeNode.cpp | 26 | ||||
-rw-r--r-- | protocols/WhatsApp/src/WhatsAPI++/WALogin.cpp | 44 | ||||
-rw-r--r-- | protocols/WhatsApp/src/WhatsAPI++/WALogin.h | 4 | ||||
-rw-r--r-- | protocols/WhatsApp/src/chat.cpp | 4 | ||||
-rw-r--r-- | protocols/WhatsApp/src/connection.cpp | 28 | ||||
-rw-r--r-- | protocols/WhatsApp/src/contacts.cpp | 49 | ||||
-rw-r--r-- | protocols/WhatsApp/src/dialogs.cpp | 16 | ||||
-rw-r--r-- | protocols/WhatsApp/src/messages.cpp | 12 | ||||
-rw-r--r-- | protocols/WhatsApp/src/proto.cpp | 71 | ||||
-rw-r--r-- | protocols/WhatsApp/src/proto.h | 55 | ||||
-rw-r--r-- | 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<unsigned char> 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<unsigned char>* data, vector<ProtocolTreeNode*> *children)
+ProtocolTreeNode::ProtocolTreeNode(const string &_tag, vector<unsigned char>* _data, vector<ProtocolTreeNode*> *_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<ProtocolTreeNode*>(1);
- (*this->children)[0] = child;
+ this->children = new std::vector<ProtocolTreeNode*>();
+ 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<unsigned char>* WALogin::login(const std::vector<unsigned char>& 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<unsigned char>* WALogin::login(const std::vector<unsigned char>& aut void WALogin::sendResponse(const std::vector<unsigned char>& challengeData)
{
std::vector<unsigned char>* 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<unsigned char>& existingChallenge)
@@ -73,8 +73,8 @@ void WALogin::sendAuth(const std::vector<unsigned char>& 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<unsigned char>* WALogin::getAuthBlob(const std::vector<unsigned char>& nonce)
@@ -82,31 +82,31 @@ std::vector<unsigned char>* WALogin::getAuthBlob(const std::vector<unsigned char unsigned char out[4*20];
KeyStream::keyFromPasswordAndNonce(this->password, 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<unsigned char>* list = new std::vector<unsigned char>(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<unsigned char>* 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<unsigned char>* WALogin::readFeaturesUntilChallengeOrSuccess() std::vector<unsigned char> challengedata(root->data->begin(), root->data->end());
delete root;
this->sendResponse(challengedata);
- connection->logData("Send response");
+ m_pConnection->logData("Send response");
std::vector<unsigned char> data = this->readSuccess();
- connection->logData("Read success");
+ m_pConnection->logData("Read success");
return new std::vector<unsigned char>(data.begin(), data.end());
}
if (ProtocolTreeNode::tagEquals(root, "success")) {
@@ -131,7 +131,7 @@ std::vector<unsigned char>* 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<unsigned char> 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<unsigned char>* getAuthBlob(const std::vector<unsigned char>& nonce);
void sendResponse(const std::vector<unsigned char>& 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<GCHOOK*>(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<unsigned char> *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<string> ids;
ids.push_back(from);
- this->connection->sendGetPictureIds(ids);
+ m_pConnection->sendGetPictureIds(ids);
}
}
@@ -271,7 +258,7 @@ void WhatsAppProto::onSendGetPictureIds(std::map<string, string>* 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<string>& 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<FMessage*>(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<WhatsAppProto>(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<string> &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<string, MCONTACT> hContactByJid;
map<MCONTACT, map<MCONTACT, bool>> 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<string>& 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
|