summaryrefslogtreecommitdiff
path: root/protocols/WhatsApp/src
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/WhatsApp/src')
-rw-r--r--protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp26
-rw-r--r--protocols/WhatsApp/src/WhatsAPI++/WAConnection.h34
-rw-r--r--protocols/WhatsApp/src/contacts.cpp51
-rw-r--r--protocols/WhatsApp/src/proto.cpp68
-rw-r--r--protocols/WhatsApp/src/proto.h19
-rw-r--r--protocols/WhatsApp/src/theme.cpp1
-rw-r--r--protocols/WhatsApp/src/version.h2
7 files changed, 94 insertions, 107 deletions
diff --git a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp
index 29aaec738b..27dd4aff3a 100644
--- a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp
+++ b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.cpp
@@ -650,31 +650,15 @@ void WAConnection::sendGetOwningGroups() throw (WAException)
this->mutex->unlock();
}
-void WAConnection::sendGetPicture(const std::string& jid, const std::string& type, const std::string& oldId, const std::string& newId) throw (WAException)
+void WAConnection::sendGetPicture(const std::string& jid, const std::string& type) throw (WAException)
{
- std::string id = makeId("get_picture_");
- this->pending_server_requests[id] = new IqResultGetPhotoHandler(this, jid, oldId, newId);
+ std::string id = makeId("iq_");
+ this->pending_server_requests[id] = new IqResultGetPhotoHandler(this, jid);
- ProtocolTreeNode *listNode = new ProtocolTreeNode("picture")
- << XATTR("xmlns", "w:profile:picture") << XATTR("type", type);
+ ProtocolTreeNode *listNode = new ProtocolTreeNode("picture") << XATTR("type", type);
this->out->write(ProtocolTreeNode("iq", listNode)
- << XATTR("id", id) << XATTR("to", jid) << XATTR("type", "get"));
-}
-
-void WAConnection::sendGetPictureIds(const std::vector<std::string>& jids) throw (WAException)
-{
- std::string id = makeId("get_picture_ids_");
- this->pending_server_requests[id] = new IqResultGetPictureIdsHandler(this);
-
- std::vector<ProtocolTreeNode*>* children = new std::vector<ProtocolTreeNode*>();
- for (size_t i = 0; i < jids.size(); i++) {
- ProtocolTreeNode *child = new ProtocolTreeNode("user") << XATTR("jid", jids[i]);
- children->push_back(child);
- }
-
- ProtocolTreeNode *queryNode = new ProtocolTreeNode("list", NULL, children) << XATTR("xmlns", "w:profile:picture");
- this->out->write(ProtocolTreeNode("iq", queryNode) << XATTR("id", id) << XATTR("type", "get"));
+ << XATTR("id", id) << XATTR("to", jid) << XATTR("xmlns", "w:profile:picture") << XATTR("type", "get"));
}
void WAConnection::sendGetPrivacyList() throw (WAException)
diff --git a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h
index 560f957634..5a5dfc5b83 100644
--- a/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h
+++ b/protocols/WhatsApp/src/WhatsAPI++/WAConnection.h
@@ -45,8 +45,7 @@ public:
virtual void onDirty(const std::map<string,string>& paramHashtable)=0;
virtual void onDirtyResponse(int paramHashtable)=0;
virtual void onRelayRequest(const std::string& paramString1, int paramInt, const std::string& paramString2)=0;
- virtual void onSendGetPictureIds(std::map<string,string>* ids)=0;
- virtual void onSendGetPicture(const std::string& jid, const std::vector<unsigned char>& data, const std::string& oldId, const std::string& newId)=0;
+ virtual void onSendGetPicture(const std::string& jid, const std::vector<unsigned char>& data, const std::string& id)=0;
virtual void onPictureChanged(const std::string& from, const std::string& author, bool set)=0;
virtual void onDeleteAccount(bool result)=0;
};
@@ -254,10 +253,8 @@ class WAConnection {
std::string oldId;
std::string newId;
public:
- IqResultGetPhotoHandler(WAConnection* con, const std::string& jid, const std::string& oldId, const std::string& newId):IqResultHandler(con) {
+ IqResultGetPhotoHandler(WAConnection* con, const std::string& jid):IqResultHandler(con) {
this->jid = jid;
- this->oldId = oldId;
- this->newId = newId;
}
virtual void parse(ProtocolTreeNode* node, const std::string& from) throw (WAException) {
const string &attributeValue = node->getAttributeValue("type");
@@ -269,7 +266,7 @@ class WAConnection {
const string &id = current->getAttributeValue("id");
if (!id.empty() && current->data != NULL && current->data->size() > 0) {
if (current->data != NULL)
- this->con->event_handler->onSendGetPicture(this->jid, *current->data, this->oldId, this->newId);
+ this->con->event_handler->onSendGetPicture(this->jid, *current->data, id);
break;
}
}
@@ -278,7 +275,7 @@ class WAConnection {
void error(ProtocolTreeNode* node) throw (WAException) {
if (this->con->event_handler != NULL) {
std::vector<unsigned char> v;
- this->con->event_handler->onSendGetPicture("error", v, "", "");
+ this->con->event_handler->onSendGetPicture("error", v, "");
}
}
};
@@ -299,26 +296,6 @@ class WAConnection {
}
};
- class IqResultGetPictureIdsHandler: public IqResultHandler {
- public:
- IqResultGetPictureIdsHandler(WAConnection* con):IqResultHandler(con) {}
- virtual void parse(ProtocolTreeNode* node, const std::string& from) throw (WAException) {
- // logData("onGetPhotoIds %s", node->toString().c_str());
- ProtocolTreeNode* groupNode = node->getChild("list");
- std::vector<ProtocolTreeNode*> children(groupNode->getAllChildren("user"));
- std::map<std::string, std::string> ids;
- for (size_t i = 0; i < children.size(); i++) {
- const string &jid = children[i]->getAttributeValue("jid");
- const string &id = children[i]->getAttributeValue("id");
- if (!jid.empty())
- ids[jid] = id;
- }
-
- if (this->con->event_handler != NULL)
- this->con->event_handler->onSendGetPictureIds(&ids);
- }
- };
-
class IqResultSendDeleteAccount: public IqResultHandler {
public:
IqResultSendDeleteAccount(WAConnection* con):IqResultHandler(con) {}
@@ -446,8 +423,7 @@ public:
void sendRemoveParticipants(const std::string& gjid, const std::vector<std::string>& participants) throw (WAException);
void sendSetNewSubject(const std::string& gjid, const std::string& subject) throw (WAException);
void sendStatusUpdate(std::string& status) throw (WAException);
- void sendGetPicture(const std::string& jid, const std::string& type, const std::string& oldId, const std::string& newId) throw (WAException);
- void sendGetPictureIds(const std::vector<std::string>& jids) throw (WAException);
+ void sendGetPicture(const std::string& jid, const std::string& type) throw (WAException);
void sendSetPicture(const std::string& jid, std::vector<unsigned char>* data) throw (WAException);
void sendNotificationReceived(const std::string& from, const std::string& id) throw(WAException);
void sendDeleteAccount() throw(WAException);
diff --git a/protocols/WhatsApp/src/contacts.cpp b/protocols/WhatsApp/src/contacts.cpp
index 39b7c48849..1efadd1876 100644
--- a/protocols/WhatsApp/src/contacts.cpp
+++ b/protocols/WhatsApp/src/contacts.cpp
@@ -128,11 +128,6 @@ void WhatsAppProto::ProcessBuddyList(void*)
ptrA jid(getStringA(hContact, WHATSAPP_KEY_ID));
if (jid) {
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(string(jid));
- }
-
if (getByte(hContact, "SimpleChatRoom", 0) == 0) {
m_pConnection->sendQueryLastOnline((char*)jid);
m_pConnection->sendPresenceSubscriptionRequest((char*)jid);
@@ -142,12 +137,6 @@ void WhatsAppProto::ProcessBuddyList(void*)
}
}
- if (jids.size() > 0) {
- try {
- m_pConnection->sendGetPictureIds(jids);
- }
- CODE_BLOCK_CATCH_ALL
- }
try {
m_pConnection->sendGetGroups();
m_pConnection->sendGetOwningGroups();
@@ -199,34 +188,30 @@ void WhatsAppProto::onPictureChanged(const std::string& from, const std::string&
if (this->isOnline()) {
vector<string> ids;
ids.push_back(from);
- m_pConnection->sendGetPictureIds(ids);
+ m_pConnection->sendGetPicture(from, "image");
}
}
-void WhatsAppProto::onSendGetPicture(const std::string& jid, const std::vector<unsigned char>& data, const std::string& oldId, const std::string& newId)
+void WhatsAppProto::onSendGetPicture(const std::string& jid, const std::vector<unsigned char>& data, const std::string& id)
{
MCONTACT hContact = this->ContactIDToHContact(jid);
if (hContact) {
debugLogA("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");
+ std::tstring filename = GetAvatarFileName(hContact);
FILE *f = _tfopen(filename.c_str(), _T("wb"));
- int r = (int)fwrite(std::string(data.begin(), data.end()).c_str(), 1, data.size(), f);
+ size_t r = 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;
+ _tcsncpy_s(ai.filename, filename.c_str(), _TRUNCATE);
int ackResult;
if (r > 0) {
- setString(hContact, WHATSAPP_KEY_AVATAR_ID, newId.c_str());
+ setString(hContact, WHATSAPP_KEY_AVATAR_ID, id.c_str());
ackResult = ACKRESULT_SUCCESS;
}
else {
@@ -236,30 +221,6 @@ void WhatsAppProto::onSendGetPicture(const std::string& jid, const std::vector<u
}
}
-void WhatsAppProto::onSendGetPictureIds(std::map<string, string>* ids)
-{
- for (std::map<string, string>::iterator it = ids->begin(); it != ids->end(); ++it) {
- MCONTACT hContact = this->AddToContactList(it->first);
- if (hContact != NULL) {
- DBVARIANT dbv;
- std::string oldId;
- if (getString(hContact, WHATSAPP_KEY_AVATAR_ID, &dbv))
- oldId = "";
- else {
- oldId = dbv.pszVal;
- db_free(&dbv);
- }
-
- if (it->second.size() > 0 && it->second.compare(oldId) != 0) {
- try {
- m_pConnection->sendGetPicture(it->first, "image", oldId, it->second);
- }
- CODE_BLOCK_CATCH_ALL
- }
- }
- }
-}
-
TCHAR* WhatsAppProto::GetContactDisplayName(const string& jid)
{
MCONTACT hContact = this->ContactIDToHContact(jid);
diff --git a/protocols/WhatsApp/src/proto.cpp b/protocols/WhatsApp/src/proto.cpp
index fcd64ebd8a..eaf6b3d358 100644
--- a/protocols/WhatsApp/src/proto.cpp
+++ b/protocols/WhatsApp/src/proto.cpp
@@ -21,6 +21,9 @@ WhatsAppProto::WhatsAppProto(const char* proto_name, const TCHAR* username) :
CreateProtoService(PS_JOINCHAT, &WhatsAppProto::OnJoinChat);
CreateProtoService(PS_LEAVECHAT, &WhatsAppProto::OnLeaveChat);
+ CreateProtoService(PS_GETAVATARINFOT, &WhatsAppProto::GetAvatarInfo);
+ CreateProtoService(PS_GETAVATARCAPS, &WhatsAppProto::GetAvatarCaps);
+
HookProtoEvent(ME_OPT_INITIALISE, &WhatsAppProto::OnOptionsInit);
HookProtoEvent(ME_SYSTEM_MODULESLOADED, &WhatsAppProto::OnModulesLoaded);
HookProtoEvent(ME_CLIST_PREBUILDSTATUSMENU, &WhatsAppProto::OnBuildStatusMenu);
@@ -41,7 +44,10 @@ WhatsAppProto::WhatsAppProto(const char* proto_name, const TCHAR* username) :
WASocketConnection::initNetwork(m_hNetlibUser);
- def_avatar_folder_ = std::tstring(VARST(_T("%miranda_avatarcache%"))) + _T("\\") + m_tszUserName;
+ m_tszAvatarFolder = std::tstring(VARST(_T("%miranda_avatarcache%"))) + _T("\\") + m_tszUserName;
+ DWORD dwAttributes = GetFileAttributes(m_tszAvatarFolder.c_str());
+ if (dwAttributes == 0xffffffff || (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
+ CreateDirectoryTreeT(m_tszAvatarFolder.c_str());
SetAllContactStatuses(ID_STATUS_OFFLINE, true);
}
@@ -348,9 +354,65 @@ void WhatsAppProto::RequestFriendship(MCONTACT hContact)
}
}
-std::tstring WhatsAppProto::GetAvatarFolder()
+INT_PTR WhatsAppProto::GetAvatarInfo(WPARAM wParam, LPARAM lParam)
+{
+ PROTO_AVATAR_INFORMATIONT* AI = (PROTO_AVATAR_INFORMATIONT*)lParam;
+
+ ptrA id(getStringA(AI->hContact, WHATSAPP_KEY_ID));
+ if (id == NULL)
+ return GAIR_NOAVATAR;
+
+ std::tstring tszFileName = GetAvatarFileName(AI->hContact);
+ _tcsncpy_s(AI->filename, tszFileName.c_str(), _TRUNCATE);
+ AI->format = PA_FORMAT_JPEG;
+
+ ptrA szAvatarId(getStringA(AI->hContact, WHATSAPP_KEY_AVATAR_ID));
+ if (szAvatarId == NULL || (wParam & GAIF_FORCE) != 0)
+ if (AI->hContact != NULL && m_pConnection != NULL) {
+ m_pConnection->sendGetPicture((const char*)id, "image");
+ return GAIR_WAITFOR;
+ }
+
+ debugLogA("No avatar");
+ return GAIR_NOAVATAR;
+}
+
+INT_PTR WhatsAppProto::GetAvatarCaps(WPARAM wParam, LPARAM lParam)
+{
+ switch (wParam) {
+ case AF_PROPORTION:
+ return PIP_SQUARE;
+
+ case AF_FORMATSUPPORTED: // Jabber supports avatars of virtually all formats
+ return PA_FORMAT_JPEG;
+
+ case AF_ENABLED:
+ return TRUE;
+
+ case AF_MAXSIZE:
+ POINT *size = (POINT*)lParam;
+ if (size)
+ size->x = size->y = 96;
+ return 0;
+ }
+ return -1;
+}
+
+std::tstring WhatsAppProto::GetAvatarFileName(MCONTACT hContact)
{
- return def_avatar_folder_;
+ std::tstring result = m_tszAvatarFolder + _T("\\");
+
+ std::string jid;
+ if (hContact != NULL) {
+ ptrA szId(getStringA(hContact, "ID"));
+ if (szId == NULL)
+ return _T("");
+
+ jid = szId;
+ }
+ else jid = this->jid;
+
+ return result + std::tstring(_A2T(jid.c_str())) + _T(".jpg");
}
LRESULT CALLBACK PopupDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
diff --git a/protocols/WhatsApp/src/proto.h b/protocols/WhatsApp/src/proto.h
index a55d357e3f..25f145be59 100644
--- a/protocols/WhatsApp/src/proto.h
+++ b/protocols/WhatsApp/src/proto.h
@@ -74,12 +74,12 @@ public:
INT_PTR __cdecl OnJoinChat(WPARAM, LPARAM);
INT_PTR __cdecl OnLeaveChat(WPARAM, LPARAM);
INT_PTR __cdecl OnCreateGroup(WPARAM, LPARAM);
- int __cdecl OnOptionsInit(WPARAM, LPARAM);
- int __cdecl OnModulesLoaded(WPARAM, LPARAM);
//////////////////////////////////////////////////////////////////////////////////////
// Events
+ int __cdecl OnOptionsInit(WPARAM, LPARAM);
+ int __cdecl OnModulesLoaded(WPARAM, LPARAM);
int __cdecl OnBuildStatusMenu(WPARAM, LPARAM);
int __cdecl OnChatOutgoing(WPARAM, LPARAM);
int __cdecl OnPrebuildContactMenu(WPARAM, LPARAM);
@@ -143,10 +143,18 @@ private:
LONG m_iSerial;
- std::tstring GetAvatarFolder();
void ToggleStatusMenuItems(BOOL bEnable);
//////////////////////////////////////////////////////////////////////////////////////
+ // Avatars
+
+ std::tstring GetAvatarFileName(MCONTACT);
+ std::tstring m_tszAvatarFolder;
+
+ INT_PTR __cdecl GetAvatarInfo(WPARAM, LPARAM);
+ INT_PTR __cdecl GetAvatarCaps(WPARAM, LPARAM);
+
+ //////////////////////////////////////////////////////////////////////////////////////
// Handles, Locks
HGENMENU m_hMenuRoot;
@@ -156,8 +164,6 @@ private:
HANDLE log_lock_;
HANDLE update_loop_lock_;
- std::tstring def_avatar_folder_;
-
WASocketConnection *conn;
WAConnection *m_pConnection;
Mutex connMutex;
@@ -188,8 +194,7 @@ protected:
virtual void onDirty(const std::map<string, string>& paramHashtable) { }
virtual void onDirtyResponse(int paramHashtable) { }
virtual void onRelayRequest(const std::string &paramString1, int paramInt, const std::string &paramString2) { }
- virtual void onSendGetPictureIds(std::map<string, string>* ids);
- virtual void onSendGetPicture(const std::string &jid, const std::vector<unsigned char>& data, const std::string &oldId, const std::string &newId);
+ virtual void onSendGetPicture(const std::string &jid, const std::vector<unsigned char>& data, const std::string &id);
virtual void onPictureChanged(const std::string &from, const std::string &author, bool set);
virtual void onDeleteAccount(bool result) { }
diff --git a/protocols/WhatsApp/src/theme.cpp b/protocols/WhatsApp/src/theme.cpp
index 576407ca91..94e46e8b14 100644
--- a/protocols/WhatsApp/src/theme.cpp
+++ b/protocols/WhatsApp/src/theme.cpp
@@ -81,7 +81,6 @@ void WhatsAppProto::InitContactMenus()
::HookEvent(ME_CLIST_PREBUILDCONTACTMENU, PrebuildContactMenu);
CLISTMENUITEM mi = { sizeof(mi) };
-
mi.position = -2000006100;
mi.icolibItem = GetIconHandle("leaveGroup");
mi.pszName = GetIconDescription("leaveGroup");
diff --git a/protocols/WhatsApp/src/version.h b/protocols/WhatsApp/src/version.h
index 6dc5649787..6d60ffbd86 100644
--- a/protocols/WhatsApp/src/version.h
+++ b/protocols/WhatsApp/src/version.h
@@ -1,7 +1,7 @@
#define __MAJOR_VERSION 0
#define __MINOR_VERSION 1
#define __RELEASE_NUM 2
-#define __BUILD_NUM 3
+#define __BUILD_NUM 4
#include <stdver.h>