summaryrefslogtreecommitdiff
path: root/protocols/WhatsApp
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2015-01-28 16:30:05 +0000
committerGeorge Hazan <george.hazan@gmail.com>2015-01-28 16:30:05 +0000
commit52c57ef89cc24bdb8c70908f544ae86fd87db129 (patch)
treebbbeb2b8ffa4109a50bae561c2e00aad9e565068 /protocols/WhatsApp
parentf546c968c4ee1add671e8b6545d52dece95cd3f5 (diff)
- statusbar icon added to notify user that a message was read;
- FMessage own numbering removed as atavism; - WAConnection::msg_id followed FMessage::id on its road to hell - WhatsAppProto::GetSerial() added as the only method that increments message numbers git-svn-id: http://svn.miranda-ng.org/main/trunk@11941 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/WhatsApp')
-rw-r--r--protocols/WhatsApp/src/WhatsAPI++/FMessage.cpp44
-rw-r--r--protocols/WhatsApp/src/WhatsAPI++/FMessage.h23
-rw-r--r--protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp78
-rw-r--r--protocols/WhatsApp/src/WhatsAPI++/WAConnection.h1
-rw-r--r--protocols/WhatsApp/src/main.cpp1
-rw-r--r--protocols/WhatsApp/src/messages.cpp19
-rw-r--r--protocols/WhatsApp/src/proto.cpp3
-rw-r--r--protocols/WhatsApp/src/proto.h4
-rw-r--r--protocols/WhatsApp/src/utils.cpp21
-rw-r--r--protocols/WhatsApp/src/utils.h2
10 files changed, 84 insertions, 112 deletions
diff --git a/protocols/WhatsApp/src/WhatsAPI++/FMessage.cpp b/protocols/WhatsApp/src/WhatsAPI++/FMessage.cpp
index a684d1e3e3..e3c3367b04 100644
--- a/protocols/WhatsApp/src/WhatsAPI++/FMessage.cpp
+++ b/protocols/WhatsApp/src/WhatsAPI++/FMessage.cpp
@@ -9,15 +9,9 @@
#include "utilities.h"
-//SDL_mutex* FMessage::generating_lock = SDL_CreateMutex();
-IMutex* FMessage::generating_lock = NULL;
-int FMessage::generating_id = 0;
-std::string FMessage::generating_header = Utilities::intToStr(static_cast<int> (time(NULL))).append("-");
-
-
-FMessage::FMessage()
+FMessage::FMessage() :
+ key("", false, "")
{
- this->key = NULL;
this->timestamp = 0;
this->media_wa_type = 0;
this->longitude = 0;
@@ -29,15 +23,9 @@ FMessage::FMessage()
this->data = "";
}
-FMessage::FMessage(const std::string& remote_jid, bool from_me, const std::string& data)
+FMessage::FMessage(const std::string &remote_jid, bool from_me, const std::string &id) :
+ key(remote_jid, from_me, id)
{
- Key* local_key;
- FMessage::generating_lock->lock();
- FMessage::generating_id++;
- local_key = new Key(remote_jid, from_me, generating_header + Utilities::intToStr(generating_id));
- this->key = local_key;
- FMessage::generating_lock->unlock();
- this->data = data;
this->timestamp = time(NULL);
this->media_wa_type = 0;
this->longitude = 0;
@@ -48,28 +36,6 @@ FMessage::FMessage(const std::string& remote_jid, bool from_me, const std::strin
this->media_url = "";
}
-std::string FMessage::nextKeyIdNumber()
-{
- int id = 0;
- FMessage::generating_lock->lock();
- id = (FMessage::generating_id++);
- FMessage::generating_lock->unlock();
- return generating_header + (Utilities::intToStr(id));
-}
-
-FMessage::FMessage(Key* key)
-{
- this->key = key;
- this->timestamp = 0;
- this->media_wa_type = 0;
- this->longitude = 0;
- this->latitude = 0;
- this->media_duration_seconds = 0;
- this->media_size = 0;
- this->media_name = "";
- this->media_url = "";
-}
-
std::string FMessage::getMessage_WA_Type_StrValue(unsigned char type)
{
switch (type) {
@@ -94,8 +60,6 @@ std::string FMessage::getMessage_WA_Type_StrValue(unsigned char type)
FMessage::~FMessage()
{
- if (this->key != NULL)
- delete key;
}
Key::Key(const std::string& remote_jid, bool from_me, const std::string& id)
diff --git a/protocols/WhatsApp/src/WhatsAPI++/FMessage.h b/protocols/WhatsApp/src/WhatsAPI++/FMessage.h
index fb523d9c8e..e53b7d88dd 100644
--- a/protocols/WhatsApp/src/WhatsAPI++/FMessage.h
+++ b/protocols/WhatsApp/src/WhatsAPI++/FMessage.h
@@ -15,8 +15,8 @@
#include <time.h>
#include "IMutex.h"
-class Key {
-public:
+struct Key
+{
std::string remote_jid;
bool from_me;
std::string id;
@@ -26,16 +26,9 @@ public:
};
-class FMessage {
-private:
- static int generating_id;
- static std::string generating_header;
-
-
-public:
- static IMutex* generating_lock; // #WORKAROUND
-
- Key* key;
+struct FMessage
+{
+ Key key;
unsigned char media_wa_type;
std::string data;
long long timestamp;
@@ -79,12 +72,10 @@ public:
};
static std::string getMessage_WA_Type_StrValue(unsigned char type);
- static std::string nextKeyIdNumber();
- static unsigned char getMessage_WA_Type(const std::string& typeString);
+ static unsigned char getMessage_WA_Type(const std::string &typeString);
FMessage();
- FMessage(const std::string& remote_jid, bool from_me = true, const std::string& data = "");
- FMessage(Key* key);
+ FMessage(const std::string &remote_jid, bool from_me, const std::string &id);
virtual ~FMessage();
};
diff --git a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp
index c87f88b619..29aaec738b 100644
--- a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp
+++ b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp
@@ -105,7 +105,6 @@ WAConnection::WAConnection(const std::string &user, const std::string &resource,
this->in = NULL;
this->out = NULL;
- this->msg_id = 0;
this->retry = true;
this->user = user;
@@ -269,7 +268,7 @@ void WAConnection::parseAck(ProtocolTreeNode *node) throw(WAException)
const string &ts = node->getAttributeValue("t");
if (cls == "message" && this->event_handler != NULL) {
- FMessage msg(new Key(from, true, id));
+ FMessage msg(from, true, id);
msg.status = FMessage::STATUS_RECEIVED_BY_SERVER;
this->event_handler->onMessageStatusUpdate(&msg);
}
@@ -312,13 +311,11 @@ void WAConnection::parseMessage(ProtocolTreeNode *messageNode) throw (WAExceptio
errorCode = atoi(errorNode->getAttributeValue("code").c_str());
}
- Key* key = new Key(from, true, id);
- FMessage* message = new FMessage(key);
- message->status = FMessage::STATUS_SERVER_BOUNCE;
+ FMessage message(from, true, id);
+ message.status = FMessage::STATUS_SERVER_BOUNCE;
if (this->event_handler != NULL)
- this->event_handler->onMessageError(message, errorCode);
- delete message;
+ this->event_handler->onMessageError(&message, errorCode);
}
else if (typeAttribute == "subject") {
bool receiptRequested = false;
@@ -337,29 +334,28 @@ void WAConnection::parseMessage(ProtocolTreeNode *messageNode) throw (WAExceptio
sendSubjectReceived(from, id);
}
else if (typeAttribute == "chat" || typeAttribute == "text") {
- FMessage* fmessage = new FMessage();
- fmessage->wants_receipt = false;
- fmessage->timestamp = atoi(attribute_t.c_str());
+ FMessage fmessage;
+ fmessage.wants_receipt = false;
+ fmessage.timestamp = atoi(attribute_t.c_str());
bool duplicate = false;
std::vector<ProtocolTreeNode*> messageChildren(messageNode->getAllChildren());
for (size_t i = 0; i < messageChildren.size(); i++) {
ProtocolTreeNode *childNode = messageChildren[i];
if (ProtocolTreeNode::tagEquals(childNode, "body")) {
- Key* key = new Key(from, false, id);
- fmessage->key = key;
- fmessage->remote_resource = author;
- fmessage->data = childNode->getDataAsString();
- fmessage->status = FMessage::STATUS_UNSENT;
+ fmessage.key = Key(from, false, id);
+ fmessage.remote_resource = author;
+ fmessage.data = childNode->getDataAsString();
+ fmessage.status = FMessage::STATUS_UNSENT;
}
else if (ProtocolTreeNode::tagEquals(childNode, "media") && !id.empty()) {
- fmessage->media_wa_type = FMessage::getMessage_WA_Type(childNode->getAttributeValue("type"));
- fmessage->media_url = childNode->getAttributeValue("url");
- fmessage->media_name = childNode->getAttributeValue("file");
- fmessage->media_size = Utilities::parseLongLong(childNode->getAttributeValue("size"));
- fmessage->media_duration_seconds = atoi(childNode->getAttributeValue("seconds").c_str());
+ fmessage.media_wa_type = FMessage::getMessage_WA_Type(childNode->getAttributeValue("type"));
+ fmessage.media_url = childNode->getAttributeValue("url");
+ fmessage.media_name = childNode->getAttributeValue("file");
+ fmessage.media_size = Utilities::parseLongLong(childNode->getAttributeValue("size"));
+ fmessage.media_duration_seconds = atoi(childNode->getAttributeValue("seconds").c_str());
- if (fmessage->media_wa_type == FMessage::WA_TYPE_LOCATION) {
+ if (fmessage.media_wa_type == FMessage::WA_TYPE_LOCATION) {
const string &latitudeString = childNode->getAttributeValue("latitude");
const string &longitudeString = childNode->getAttributeValue("longitude");
if (latitudeString.empty() || longitudeString.empty())
@@ -367,42 +363,39 @@ void WAConnection::parseMessage(ProtocolTreeNode *messageNode) throw (WAExceptio
double latitude = atof(latitudeString.c_str());
double longitude = atof(longitudeString.c_str());
- fmessage->latitude = latitude;
- fmessage->longitude = longitude;
+ fmessage.latitude = latitude;
+ fmessage.longitude = longitude;
}
- if (fmessage->media_wa_type == FMessage::WA_TYPE_CONTACT) {
+ if (fmessage.media_wa_type == FMessage::WA_TYPE_CONTACT) {
ProtocolTreeNode *contactChildNode = childNode->getChild(0);
if (contactChildNode != NULL) {
- fmessage->media_name = contactChildNode->getAttributeValue("name");
- fmessage->data = contactChildNode->getDataAsString();
+ fmessage.media_name = contactChildNode->getAttributeValue("name");
+ fmessage.data = contactChildNode->getDataAsString();
}
}
else {
const string &encoding = childNode->getAttributeValue("encoding");
if (encoding.empty() || encoding == "text")
- fmessage->data = childNode->getDataAsString();
+ fmessage.data = childNode->getDataAsString();
else {
logData("Media data encoding type '%s'", encoding.empty() ? "text" : encoding.c_str());
- fmessage->data = (childNode->data == NULL ? "" : std::string(base64_encode(childNode->data->data(), childNode->data->size())));
+ fmessage.data = (childNode->data == NULL ? "" : std::string(base64_encode(childNode->data->data(), childNode->data->size())));
}
}
- Key* key = new Key(from, false, id);
- fmessage->key = key;
- fmessage->remote_resource = author;
+ fmessage.key = Key(from, false, id);
+ fmessage.remote_resource = author;
}
}
- if (fmessage->timestamp == 0) {
- fmessage->timestamp = time(NULL);
- fmessage->offline = false;
+ if (fmessage.timestamp == 0) {
+ fmessage.timestamp = time(NULL);
+ fmessage.offline = false;
}
- if (fmessage->key != NULL && this->event_handler != NULL)
- this->event_handler->onMessageForMe(fmessage, duplicate);
-
- delete fmessage;
+ if (!fmessage.key.remote_jid.empty() && this->event_handler != NULL)
+ this->event_handler->onMessageForMe(&fmessage, duplicate);
}
else if (typeAttribute == "notification") {
logData("Notification node %s", messageNode->toString().c_str());
@@ -720,7 +713,7 @@ ProtocolTreeNode* WAConnection::getMessageNode(FMessage* message, ProtocolTreeNo
messageChildren->push_back(child);
return new ProtocolTreeNode("message", NULL, messageChildren) <<
- XATTR("to", message->key->remote_jid) << XATTR("type", "text") << XATTR("id", message->key->id) << XATTRI("t", message->timestamp);
+ XATTR("to", message->key.remote_jid) << XATTR("type", "text") << XATTR("id", message->key.id) << XATTRI("t", message->timestamp);
}
void WAConnection::sendMessage(FMessage* message) throw(WAException)
@@ -775,7 +768,7 @@ void WAConnection::sendMessageWithBody(FMessage* message) throw (WAException)
void WAConnection::sendMessageReceived(FMessage* message) throw(WAException)
{
this->out->write(ProtocolTreeNode("receipt") << XATTR("type", "read")
- << XATTR("to", message->key->remote_jid) << XATTR("id", message->key->id) << XATTRI("t", (int)time(0)));
+ << XATTR("to", message->key.remote_jid) << XATTR("id", message->key.id) << XATTRI("t", (int)time(0)));
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -837,12 +830,11 @@ void WAConnection::sendSetPicture(const std::string& jid, std::vector<unsigned c
void WAConnection::sendStatusUpdate(std::string& status) throw (WAException)
{
std::string id = this->makeId(Utilities::intToStr((int)time(NULL)));
- FMessage *message = new FMessage(new Key("s.us", true, id));
+ FMessage message("s.us", true, id);
ProtocolTreeNode *body = new ProtocolTreeNode("body", new std::vector<unsigned char>(status.begin(), status.end()), NULL);
- ProtocolTreeNode *n = getMessageNode(message, body);
+ ProtocolTreeNode *n = getMessageNode(&message, body);
this->out->write(*n);
delete n;
- delete message;
}
void WAConnection::sendSubjectReceived(const std::string& to, const std::string& id)throw(WAException)
diff --git a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h
index bbdad6c0e6..560f957634 100644
--- a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h
+++ b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h
@@ -398,7 +398,6 @@ public:
KeyStream inputKey, outputKey;
- int msg_id;
bool retry;
bool supports_receipt_acks;
time_t expire_date;
diff --git a/protocols/WhatsApp/src/main.cpp b/protocols/WhatsApp/src/main.cpp
index 1681132790..d4d607f452 100644
--- a/protocols/WhatsApp/src/main.cpp
+++ b/protocols/WhatsApp/src/main.cpp
@@ -92,7 +92,6 @@ extern "C" int __declspec(dllexport) Unload(void)
{
g_Instances.destroy();
- delete FMessage::generating_lock;
WASocketConnection::quitNetwork();
return 0;
diff --git a/protocols/WhatsApp/src/messages.cpp b/protocols/WhatsApp/src/messages.cpp
index b359616b89..b935f1d67b 100644
--- a/protocols/WhatsApp/src/messages.cpp
+++ b/protocols/WhatsApp/src/messages.cpp
@@ -26,7 +26,7 @@ void WhatsAppProto::onMessageForMe(FMessage* paramFMessage, bool paramBoolean)
msg->insert(0, std::string("[").append(paramFMessage->notifyname).append("]: "));
}
- MCONTACT hContact = this->AddToContactList(paramFMessage->key->remote_jid, 0, false,
+ MCONTACT hContact = this->AddToContactList(paramFMessage->key.remote_jid, 0, false,
isChatRoom ? NULL : paramFMessage->notifyname.c_str(), isChatRoom);
PROTORECVEVENT recv = { 0 };
@@ -54,15 +54,16 @@ int WhatsAppProto::SendMsg(MCONTACT hContact, int flags, const char *msg)
return 0;
}
- int msgId = ++this->m_pConnection->msg_id;
+ int msgId = GetSerial();
try {
time_t now = time(NULL);
std::string id = Utilities::intToStr(now) + "-" + Utilities::intToStr(msgId);
- FMessage fmsg(new Key((const char*)jid, true, id));
+ FMessage fmsg(std::string(jid), true, id);
fmsg.timestamp = now;
fmsg.data = msg;
m_pConnection->sendMessage(&fmsg);
+ utils::setStatusMessage(hContact, NULL);
}
catch (exception &e) {
debugLogA("exception: %s", e.what());
@@ -117,16 +118,22 @@ void WhatsAppProto::SendTypingWorker(void* p)
void WhatsAppProto::onMessageStatusUpdate(FMessage* fmsg)
{
- MCONTACT hContact = this->ContactIDToHContact(fmsg->key->remote_jid);
+ MCONTACT hContact = this->ContactIDToHContact(fmsg->key.remote_jid);
if (hContact == 0)
return;
if (fmsg->status == FMessage::STATUS_RECEIVED_BY_SERVER) {
- size_t delim = fmsg->key->id.find('-');
+ size_t delim = fmsg->key.id.find('-');
if (delim == string::npos)
return;
- int msgId = atoi(fmsg->key->id.substr(delim+1).c_str());
+ int msgId = atoi(fmsg->key.id.substr(delim+1).c_str());
ProtoBroadcastAck(hContact, ACKTYPE_MESSAGE, ACKRESULT_SUCCESS, (HANDLE)msgId, 0);
+
+ time_t timestamp = atol(fmsg->key.id.substr(0, delim).c_str());
+
+ TCHAR ttime[64];
+ _tcsftime(ttime, SIZEOF(ttime), _T("%X"), localtime(&timestamp));
+ utils::setStatusMessage(hContact, CMString(FORMAT, TranslateT("Message read: %s by %s"), ttime, pcli->pfnGetContactDisplayName(hContact, 0)));
}
}
diff --git a/protocols/WhatsApp/src/proto.cpp b/protocols/WhatsApp/src/proto.cpp
index cd251762c3..fcd64ebd8a 100644
--- a/protocols/WhatsApp/src/proto.cpp
+++ b/protocols/WhatsApp/src/proto.cpp
@@ -16,7 +16,6 @@ WhatsAppProto::WhatsAppProto(const char* proto_name, const TCHAR* username) :
PROTO<WhatsAppProto>(proto_name, username)
{
update_loop_lock_ = CreateEvent(NULL, false, false, NULL);
- FMessage::generating_lock = new Mutex();
CreateProtoService(PS_CREATEACCMGRUI, &WhatsAppProto::SvcCreateAccMgrUI);
CreateProtoService(PS_JOINCHAT, &WhatsAppProto::OnJoinChat);
@@ -205,7 +204,7 @@ HANDLE WhatsAppProto::SearchBasic(const PROTOCHAR* id)
return 0;
// fake - we always accept search
- SearchParam *param = new SearchParam(id, ++m_pConnection->msg_id);
+ SearchParam *param = new SearchParam(id, GetSerial());
ForkThread(&WhatsAppProto::SearchAckThread, param);
return (HANDLE)param->id;
}
diff --git a/protocols/WhatsApp/src/proto.h b/protocols/WhatsApp/src/proto.h
index 622296cdd9..a55d357e3f 100644
--- a/protocols/WhatsApp/src/proto.h
+++ b/protocols/WhatsApp/src/proto.h
@@ -129,6 +129,8 @@ public:
return getByte(hC, "SimpleChatRoom", 0) > (checkIsAdmin ? 1 : 0);
}
+ LONG GetSerial();
+
//////////////////////////////////////////////////////////////////////////////////////
// Registration
@@ -139,6 +141,8 @@ private:
//////////////////////////////////////////////////////////////////////////////////////
// Helpers
+ LONG m_iSerial;
+
std::tstring GetAvatarFolder();
void ToggleStatusMenuItems(BOOL bEnable);
diff --git a/protocols/WhatsApp/src/utils.cpp b/protocols/WhatsApp/src/utils.cpp
index 0aa95f1a16..2b9ebd2b2f 100644
--- a/protocols/WhatsApp/src/utils.cpp
+++ b/protocols/WhatsApp/src/utils.cpp
@@ -1,11 +1,14 @@
#include "common.h"
-std::string getLastErrorMsg()
+LONG WhatsAppProto::GetSerial()
{
- // Retrieve the system error message for the last-error code
+ return ::_InterlockedIncrement(&m_iSerial);
+}
+std::string getLastErrorMsg()
+{
LPVOID lpMsgBuf;
- DWORD dw = WSAGetLastError();
+ DWORD dw = WSAGetLastError(); // retrieve the system error message for the last-error code
FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
@@ -22,6 +25,18 @@ std::string getLastErrorMsg()
return ret;
}
+void utils::setStatusMessage(MCONTACT hContact, const TCHAR *ptszMessage)
+{
+ if (ptszMessage != NULL) {
+ StatusTextData st = { 0 };
+ st.cbSize = sizeof(st);
+ st.hIcon = LoadSkinnedIcon(SKINICON_EVENT_MESSAGE);
+ _tcsncpy_s(st.tszText, ptszMessage, _TRUNCATE);
+ CallService(MS_MSG_SETSTATUSTEXT, hContact, (LPARAM)&st);
+ }
+ else CallService(MS_MSG_SETSTATUSTEXT, hContact, NULL);
+}
+
BYTE* utils::md5string(const BYTE *data, int size, BYTE *digest)
{
mir_md5_state_t md5_state;
diff --git a/protocols/WhatsApp/src/utils.h b/protocols/WhatsApp/src/utils.h
index a5b1e17592..7f0d903d1b 100644
--- a/protocols/WhatsApp/src/utils.h
+++ b/protocols/WhatsApp/src/utils.h
@@ -58,6 +58,8 @@ std::string getLastErrorMsg();
namespace utils
{
+ void setStatusMessage(MCONTACT hContact, const TCHAR *ptszMessage);
+
BYTE* md5string(const BYTE*, int, BYTE* digest);
__forceinline BYTE* md5string(const std::string &str, BYTE* digest)
{