summaryrefslogtreecommitdiff
path: root/protocols
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2021-04-22 19:00:20 +0300
committerGeorge Hazan <ghazan@miranda.im>2021-04-22 19:00:20 +0300
commit9720e70692d2130ee7f4eddf3fecdd9ce07c2e67 (patch)
tree6dad7de62fdc3df52d4f6c2bd533b97adeef6fc7 /protocols
parent265b6179424fcf1a493c2683175781dad1aaa84f (diff)
WhatsApp: presence processing
Diffstat (limited to 'protocols')
-rw-r--r--protocols/WhatsAppWeb/src/proto.h2
-rw-r--r--protocols/WhatsAppWeb/src/server.cpp55
2 files changed, 48 insertions, 9 deletions
diff --git a/protocols/WhatsAppWeb/src/proto.h b/protocols/WhatsAppWeb/src/proto.h
index 3d66a8f3ff..acbdc00b4b 100644
--- a/protocols/WhatsAppWeb/src/proto.h
+++ b/protocols/WhatsAppWeb/src/proto.h
@@ -35,6 +35,7 @@ struct WAUser
DWORD dwModifyTag;
char *szId;
SESSION_INFO *si = 0;
+ DWORD m_time1 = 0, m_time2 = 0;
};
struct WAMessage
@@ -137,6 +138,7 @@ class WhatsAppProto : public PROTO<WhatsAppProto>
void ProcessBlocked(const JSONNode &node);
void ProcessCmd(const JSONNode &node);
void ProcessConn(const JSONNode &node);
+ void ProcessPresence(const JSONNode &node);
/// Avatars ////////////////////////////////////////////////////////////////////////////
CMStringW GetAvatarFileName(MCONTACT hContact);
diff --git a/protocols/WhatsAppWeb/src/server.cpp b/protocols/WhatsAppWeb/src/server.cpp
index c4c4b96ad1..a75ffda4d2 100644
--- a/protocols/WhatsAppWeb/src/server.cpp
+++ b/protocols/WhatsAppWeb/src/server.cpp
@@ -67,6 +67,20 @@ void WhatsAppProto::OnLoggedOut(void)
void WhatsAppProto::SendKeepAlive()
{
WebSocket_Send(m_hServerConn, "?,,", 3);
+
+ time_t now = time(0);
+
+ for (auto &it : m_arUsers) {
+ if (it->m_time1 && now - it->m_time1 >= 1200) { // 20 minutes
+ setWord(it->hContact, "Status", ID_STATUS_NA);
+ it->m_time1 = 0;
+ it->m_time2 = now;
+ }
+ else if (it->m_time2 && now - it->m_time2 >= 1200) { // 20 minutes
+ setWord(it->hContact, "Status", ID_STATUS_OFFLINE);
+ it->m_time2 = 0;
+ }
+ }
}
/////////////////////////////////////////////////////////////////////////////////////////
@@ -187,13 +201,14 @@ void WhatsAppProto::OnRestoreSession2(const JSONNode &root)
if (status != 200) {
debugLogA("Attempt to restore session failed with error %d", status);
- // if (status == 401 || status == 419) {
- // delSetting(DBKEY_ENC_KEY);
- // delSetting(DBKEY_MAC_KEY);
- // delSetting(DBKEY_CLIENT_ID);
- // delSetting(DBKEY_CLIENT_TOKEN);
- // delSetting(DBKEY_SERVER_TOKEN);
- // }
+ if (status == 401 || status == 419) {
+ POPUPDATAW Popup = {};
+ Popup.lchIcon = IcoLib_GetIconByHandle(Skin_GetIconHandle(SKINICON_ERROR));
+ wcsncpy_s(Popup.lpwzText, TranslateT("You need to launch WhatsApp on your phone"), _TRUNCATE);
+ wcsncpy_s(Popup.lpwzContactName, m_tszUserName, _TRUNCATE);
+ Popup.iSeconds = 10;
+ PUAddPopupW(&Popup);
+ }
ShutdownSession();
return;
@@ -342,11 +357,13 @@ bool WhatsAppProto::ServerThreadWorker()
switch (hdr.opCode) {
case 1: // json packet
case 2: // binary packet
- if (hdr.bIsFinal) {
- // process a packet here
+ // process a packet here
+ {
const char *pos = strchr(start, ',');
if (pos != nullptr)
pos++;
+ else
+ pos = start;
size_t dataSize = hdr.payloadSize - size_t(pos - start);
// try to decode
@@ -420,6 +437,7 @@ bool WhatsAppProto::ServerThreadWorker()
}
}
+ debugLogA("Server connection dropped");
Netlib_CloseHandle(m_hServerConn);
m_hServerConn = nullptr;
return false;
@@ -582,6 +600,8 @@ void WhatsAppProto::ProcessPacket(const JSONNode &root)
ProcessConn(content);
else if (szType == "Cmd")
ProcessCmd(content);
+ else if (szType == "Presence")
+ ProcessPresence(content);
else if (szType == "Blocklist")
ProcessBlocked(content);
}
@@ -628,3 +648,20 @@ void WhatsAppProto::ProcessConn(const JSONNode &root)
OnLoggedIn();
}
+
+void WhatsAppProto::ProcessPresence(const JSONNode &root)
+{
+ CMStringA jid = root["id"].as_mstring();
+ if (auto *pUser = FindUser(jid)) {
+ CMStringA state(root["type"].as_mstring());
+ DWORD timestamp(_wtoi(root["t"].as_mstring()));
+ if (state == "available") {
+ setWord(pUser->hContact, "Status", ID_STATUS_ONLINE);
+ }
+ else if (state == "unavailable") {
+ setWord(pUser->hContact, "Status", ID_STATUS_AWAY);
+ pUser->m_time1 = timestamp;
+ }
+ }
+ else debugLogA("Presence from unknown contact %s ignored", jid.c_str());
+}