summaryrefslogtreecommitdiff
path: root/protocols/ICQ-WIM/src
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2021-08-10 11:09:20 +0300
committerGeorge Hazan <ghazan@miranda.im>2021-08-10 11:09:20 +0300
commit5bd2d22ff78409953ee036df93f3eb09b36ef002 (patch)
tree15b6a1a94bc14439d18bb617ef600898f2d6686b /protocols/ICQ-WIM/src
parent8cef81c096966af5775861220e67432648a29a7e (diff)
ICQ:
- fixes wrong online status detection when lastSeen == 0; - fixes correct APP_ID sending; - fixes error handling inside RAPI token generation
Diffstat (limited to 'protocols/ICQ-WIM/src')
-rw-r--r--protocols/ICQ-WIM/src/http.cpp4
-rw-r--r--protocols/ICQ-WIM/src/options.cpp6
-rw-r--r--protocols/ICQ-WIM/src/poll.cpp6
-rw-r--r--protocols/ICQ-WIM/src/proto.cpp8
-rw-r--r--protocols/ICQ-WIM/src/proto.h7
-rw-r--r--protocols/ICQ-WIM/src/server.cpp39
-rw-r--r--protocols/ICQ-WIM/src/utils.cpp13
-rw-r--r--protocols/ICQ-WIM/src/version.h2
8 files changed, 48 insertions, 37 deletions
diff --git a/protocols/ICQ-WIM/src/http.cpp b/protocols/ICQ-WIM/src/http.cpp
index 66509d6d2b..e3fc4cd62c 100644
--- a/protocols/ICQ-WIM/src/http.cpp
+++ b/protocols/ICQ-WIM/src/http.cpp
@@ -162,7 +162,7 @@ bool CIcqProto::ExecuteRequest(AsyncHttpRequest *pReq)
pReq->AddHeader("Content-Type", "application/json");
if (m_szRToken.IsEmpty()) {
- if (!RefreshRobustToken()) {
+ if (!RefreshRobustToken(pReq)) {
delete pReq;
return false;
}
@@ -203,7 +203,7 @@ bool CIcqProto::ExecuteRequest(AsyncHttpRequest *pReq)
m_szRToken.Empty();
// if token refresh succeeded, replace it in the query and push request back
- if (!RefreshRobustToken()) {
+ if (!RefreshRobustToken(pReq)) {
delete pReq;
return false;
}
diff --git a/protocols/ICQ-WIM/src/options.cpp b/protocols/ICQ-WIM/src/options.cpp
index 4775fed3f3..fae31b9ea3 100644
--- a/protocols/ICQ-WIM/src/options.cpp
+++ b/protocols/ICQ-WIM/src/options.cpp
@@ -99,7 +99,7 @@ struct CIcqRegistrationDlg : public CIcqDlgBase
bool OnApply() override
{
auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "https://www.icq.com/smsreg/loginWithPhoneNumber.php", &CIcqProto::OnLoginViaPhone);
- pReq << CHAR_PARAM("locale", "en") << CHAR_PARAM("msisdn", szMsisdn) << CHAR_PARAM("trans_id", szTrans) << CHAR_PARAM("k", ICQ_APP_ID)
+ pReq << CHAR_PARAM("locale", "en") << CHAR_PARAM("msisdn", szMsisdn) << CHAR_PARAM("trans_id", szTrans) << CHAR_PARAM("k", m_proto->appId())
<< CHAR_PARAM("r", pReq->m_reqId) << CHAR_PARAM("f", "json") << WCHAR_PARAM("sms_code", ptrW(edtCode.GetText())) << INT_PARAM("create_account", 1);
pReq->pUserInfo = this;
@@ -127,7 +127,7 @@ struct CIcqRegistrationDlg : public CIcqDlgBase
{
auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "https://www.icq.com/smsreg/requestPhoneValidation.php", &CIcqProto::OnValidateSms);
pReq << CHAR_PARAM("locale", "en") << CHAR_PARAM("msisdn", szMsisdn) << CHAR_PARAM("r", pReq->m_reqId)
- << CHAR_PARAM("smsFormatType", "human") << CHAR_PARAM("k", ICQ_APP_ID);
+ << CHAR_PARAM("smsFormatType", "human") << CHAR_PARAM("k", m_proto->appId());
pReq->pUserInfo = this;
m_proto->Push(pReq);
}
@@ -154,7 +154,7 @@ void CIcqProto::OnCheckPhone(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
auto *pNew = new AsyncHttpRequest(CONN_MAIN, REQUEST_GET, "https://www.icq.com/smsreg/normalizePhoneNumber.php", &CIcqProto::OnNormalizePhone);
pNew << CHAR_PARAM("countryCode", szPrefix) << CHAR_PARAM("phoneNumber", szPhoneNumber.c_str() + szPrefix.GetLength())
- << CHAR_PARAM("k", ICQ_APP_ID) << CHAR_PARAM("r", pReq->m_reqId);
+ << CHAR_PARAM("k", appId()) << CHAR_PARAM("r", pReq->m_reqId);
pNew->pUserInfo = pDlg;
Push(pNew);
}
diff --git a/protocols/ICQ-WIM/src/poll.cpp b/protocols/ICQ-WIM/src/poll.cpp
index 918782e5cc..a7e59c3744 100644
--- a/protocols/ICQ-WIM/src/poll.cpp
+++ b/protocols/ICQ-WIM/src/poll.cpp
@@ -324,11 +324,7 @@ void CIcqProto::ProcessPresence(const JSONNode &ev)
if (pCache == nullptr)
return;
- int iNewStatus = StatusFromString(ev["state"].as_mstring());
-
- int iLastSeen = ev["lastseen"].as_int();
- if (iLastSeen == 0)
- iNewStatus = ID_STATUS_ONLINE;
+ int iNewStatus = StatusFromPresence(ev, pCache->m_hContact);
// major crutch dedicated to the official client behaviour to go offline
// when its window gets closed. we change the status of a contact to the
diff --git a/protocols/ICQ-WIM/src/proto.cpp b/protocols/ICQ-WIM/src/proto.cpp
index 6504dba8cb..a228835cf3 100644
--- a/protocols/ICQ-WIM/src/proto.cpp
+++ b/protocols/ICQ-WIM/src/proto.cpp
@@ -57,8 +57,8 @@ CIcqProto::CIcqProto(const char *aProtoName, const wchar_t *aUserName) :
m_bErrorPopups(this, "ShowErrorPopups", true),
m_bLaunchMailbox(this, "LaunchMailbox", true)
{
- db_set_resident(m_szModuleName, "IdleTS");
- db_set_resident(m_szModuleName, "OnlineTS");
+ db_set_resident(m_szModuleName, DB_KEY_IDLE);
+ db_set_resident(m_szModuleName, DB_KEY_ONLINETS);
m_isMra = !stricmp(Proto_GetAccount(m_szModuleName)->szProtoName, "MRA");
@@ -562,7 +562,7 @@ HANDLE CIcqProto::SendFile(MCONTACT hContact, const wchar_t *szDescription, wcha
auto *pReq = new AsyncHttpRequest(CONN_NONE, REQUEST_GET, "https://files.icq.com/files/init", &CIcqProto::OnFileInit);
pReq << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("client", "icq") << CHAR_PARAM("f", "json") << WCHAR_PARAM("filename", pTransfer->m_wszShortName)
- << CHAR_PARAM("k", ICQ_APP_ID) << INT_PARAM("size", statbuf.st_size) << INT_PARAM("ts", TS());
+ << CHAR_PARAM("k", appId()) << INT_PARAM("size", statbuf.st_size) << INT_PARAM("ts", TS());
CalcHash(pReq);
pReq->pUserInfo = pTransfer;
Push(pReq);
@@ -589,7 +589,7 @@ int CIcqProto::SendMsg(MCONTACT hContact, int, const char *pszSrc)
m_arOwnIds.insert(pOwn);
}
- pReq << AIMSID(this) << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("k", ICQ_APP_ID) << CHAR_PARAM("mentions", "")
+ pReq << AIMSID(this) << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("k", appId()) << CHAR_PARAM("mentions", "")
<< CHAR_PARAM("message", pszSrc) << CHAR_PARAM("offlineIM", "true") << CHAR_PARAM("t", szUserid) << INT_PARAM("ts", TS());
Push(pReq);
return id;
diff --git a/protocols/ICQ-WIM/src/proto.h b/protocols/ICQ-WIM/src/proto.h
index c6f0ff9502..1326120f80 100644
--- a/protocols/ICQ-WIM/src/proto.h
+++ b/protocols/ICQ-WIM/src/proto.h
@@ -274,6 +274,7 @@ class CIcqProto : public PROTO<CIcqProto>
void Json2string(MCONTACT, const JSONNode&, const char *szJson, const char *szSetting);
MCONTACT ParseBuddyInfo(const JSONNode &buddy, MCONTACT hContact = INVALID_CONTACT_ID);
void ParseMessage(MCONTACT hContact, __int64 &lastMsgId, const JSONNode &msg, bool bCreateRead, bool bLocalTime);
+ int StatusFromPresence(const JSONNode &presence, MCONTACT hContact);
void OnLoggedIn(void);
void OnLoggedOut(void);
@@ -376,7 +377,7 @@ class CIcqProto : public PROTO<CIcqProto>
bool ExecuteRequest(AsyncHttpRequest*);
bool IsQueueEmpty();
void Push(MHttpRequest*);
- bool RefreshRobustToken();
+ bool RefreshRobustToken(AsyncHttpRequest *pReq);
////////////////////////////////////////////////////////////////////////////////////////
// cache
@@ -474,6 +475,10 @@ public:
{ return time(0) - m_iTimeShift;
}
+ __forceinline const char *appId() const
+ { return (m_isMra) ? MRA_APP_ID : ICQ_APP_ID;
+ }
+
void SetPermitDeny(const CMStringW &userId, bool bAllow);
};
diff --git a/protocols/ICQ-WIM/src/server.cpp b/protocols/ICQ-WIM/src/server.cpp
index 5e08e895e7..cb0ed62849 100644
--- a/protocols/ICQ-WIM/src/server.cpp
+++ b/protocols/ICQ-WIM/src/server.cpp
@@ -100,7 +100,7 @@ void CIcqProto::CheckPassword()
}
else {
auto *pReq = new AsyncHttpRequest(CONN_MAIN, REQUEST_POST, "https://api.login.icq.net/auth/clientLogin", &CIcqProto::OnCheckPassword);
- pReq << CHAR_PARAM("clientName", "Miranda NG") << CHAR_PARAM("clientVersion", mirVer) << CHAR_PARAM("devId", ICQ_APP_ID)
+ pReq << CHAR_PARAM("clientName", "Miranda NG") << CHAR_PARAM("clientVersion", mirVer) << CHAR_PARAM("devId", appId())
<< CHAR_PARAM("f", "json") << CHAR_PARAM("tokenType", "longTerm") << WCHAR_PARAM("s", m_szOwnId) << CHAR_PARAM("pwd", m_szPassword);
#ifndef _DEBUG
pReq->flags |= NLHRF_NODUMPSEND;
@@ -348,9 +348,6 @@ MCONTACT CIcqProto::ParseBuddyInfo(const JSONNode &buddy, MCONTACT hContact)
}
else delSetting(hContact, "MirVer");
- CMStringW str(buddy["state"].as_mstring());
- WORD wStatus = StatusFromString(str);
-
const JSONNode &var = buddy["friendly"];
if (var)
setWString(hContact, "Nick", var.as_mstring());
@@ -365,12 +362,7 @@ MCONTACT CIcqProto::ParseBuddyInfo(const JSONNode &buddy, MCONTACT hContact)
Json2string(hContact, buddy, "phoneNumber", "Phone");
Json2string(hContact, buddy, "workNumber", "CompanyPhone");
- // zero here means that a contact is currently online
- int lastSeen = buddy["lastseen"].as_int();
- setDword(hContact, DB_KEY_LASTSEEN, lastSeen ? lastSeen : time(0));
- if (lastSeen == 0)
- wStatus = ID_STATUS_ONLINE;
- setDword(hContact, "Status", wStatus);
+ setDword(hContact, "Status", StatusFromPresence(buddy, hContact));
Json2int(hContact, buddy, "official", "Official");
Json2int(hContact, buddy, "onlineTime", DB_KEY_ONLINETS);
@@ -401,7 +393,7 @@ MCONTACT CIcqProto::ParseBuddyInfo(const JSONNode &buddy, MCONTACT hContact)
}
}
- str = profile["gender"].as_mstring();
+ CMStringW str = profile["gender"].as_mstring();
if (!str.IsEmpty()) {
if (str == "male")
setByte(hContact, "Gender", 'M');
@@ -416,7 +408,7 @@ MCONTACT CIcqProto::ParseBuddyInfo(const JSONNode &buddy, MCONTACT hContact)
}
}
- str = buddy["statusMsg"].as_mstring();
+ CMStringW str = buddy["statusMsg"].as_mstring();
if (str.IsEmpty())
db_unset(hContact, "CList", "StatusMsg");
else
@@ -558,7 +550,7 @@ void CIcqProto::ParseMessage(MCONTACT hContact, __int64 &lastMsgId, const JSONNo
ProtoChainRecvMsg(hContact, &pre);
}
-bool CIcqProto::RefreshRobustToken()
+bool CIcqProto::RefreshRobustToken(AsyncHttpRequest *pOrigReq)
{
if (!m_szRToken.IsEmpty())
return true;
@@ -569,13 +561,18 @@ bool CIcqProto::RefreshRobustToken()
#endif
int ts = TS();
- pReq << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("k", ICQ_APP_ID) << CHAR_PARAM("nonce", CMStringA(FORMAT, "%d-%d", ts, rand() % 10)) << INT_PARAM("ts", ts);
+ pReq << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("k", appId()) << CHAR_PARAM("nonce", CMStringA(FORMAT, "%d-%d", ts, rand() % 10)) << INT_PARAM("ts", ts);
CalcHash(pReq);
CMStringA szAgent(FORMAT, "%S Mail.ru Windows ICQ (version 10.0.1999)", (wchar_t*)m_szOwnId);
pReq->AddHeader("User-Agent", szAgent);
- if (!ExecuteRequest(pReq))
+ if (!ExecuteRequest(pReq)) {
+LBL_Error:
+ (this->*(pOrigReq->m_pFunc))(nullptr, pOrigReq);
return false;
+ }
+ if (m_szRToken.IsEmpty())
+ goto LBL_Error;
// now add this token
bool bRet = false;
@@ -583,11 +580,11 @@ bool CIcqProto::RefreshRobustToken()
#ifndef _DEBUG
pReq->flags |= NLHRF_NODUMPSEND;
#endif
- pReq << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("f", "json") << CHAR_PARAM("k", ICQ_APP_ID) << INT_PARAM("ts", ts)
+ pReq << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("f", "json") << CHAR_PARAM("k", appId()) << INT_PARAM("ts", ts)
<< CHAR_PARAM("client", "icq") << CHAR_PARAM("reqId", pReq->m_reqId) << CHAR_PARAM("authToken", m_szRToken);
pReq->pUserInfo = &bRet;
if (!ExecuteRequest(pReq))
- return false;
+ goto LBL_Error;
return bRet;
}
@@ -735,7 +732,7 @@ void CIcqProto::StartSession()
<< INT_PARAM("buildNumber", __BUILD_NUM) << CHAR_PARAM("deviceId", szDeviceId) << CHAR_PARAM("events", EVENTS)
<< CHAR_PARAM("f", "json") << CHAR_PARAM("imf", "plain") << CHAR_PARAM("inactiveView", "offline")
<< CHAR_PARAM("includePresenceFields", FIELDS) << CHAR_PARAM("invisible", "false")
- << CHAR_PARAM("k", ICQ_APP_ID) << INT_PARAM("mobile", 0) << CHAR_PARAM("nonce", nonce) << CHAR_PARAM("r", pReq->m_reqId)
+ << CHAR_PARAM("k", appId()) << INT_PARAM("mobile", 0) << CHAR_PARAM("nonce", nonce) << CHAR_PARAM("r", pReq->m_reqId)
<< INT_PARAM("rawMsg", 0) << INT_PARAM("sessionTimeout", 7776000) << INT_PARAM("ts", ts) << CHAR_PARAM("view", "online");
CalcHash(pReq);
@@ -877,7 +874,7 @@ void CIcqProto::OnFileContinue(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pOld
m_arOwnIds.insert(pOwn);
}
- pReq << AIMSID(this) << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("k", ICQ_APP_ID) << CHAR_PARAM("mentions", "") << WCHAR_PARAM("message", wszUrl)
+ pReq << AIMSID(this) << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("k", appId()) << CHAR_PARAM("mentions", "") << WCHAR_PARAM("message", wszUrl)
<< CHAR_PARAM("offlineIM", "true") << WCHAR_PARAM("parts", wszParts) << WCHAR_PARAM("t", GetUserId(pTransfer->pfts.hContact)) << INT_PARAM("ts", TS());
Push(pReq);
@@ -889,7 +886,7 @@ void CIcqProto::OnFileContinue(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pOld
// else send the next portion
auto *pReq = new AsyncHttpRequest(CONN_NONE, REQUEST_POST, pTransfer->m_szHost, &CIcqProto::OnFileContinue);
- pReq << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("client", "icq") << CHAR_PARAM("k", ICQ_APP_ID) << INT_PARAM("ts", TS());
+ pReq << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("client", "icq") << CHAR_PARAM("k", appId()) << INT_PARAM("ts", TS());
CalcHash(pReq);
pReq->m_szUrl.AppendChar('?');
pReq->m_szUrl += pReq->m_szParam; pReq->m_szParam.Empty();
@@ -920,7 +917,7 @@ void CIcqProto::OnFileInit(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pOld)
pTransfer->m_szHost = L"https://" + wszHost + wszUrl;
auto *pReq = new AsyncHttpRequest(CONN_NONE, REQUEST_POST, pTransfer->m_szHost, &CIcqProto::OnFileContinue);
- pReq << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("client", "icq") << CHAR_PARAM("k", ICQ_APP_ID) << INT_PARAM("ts", TS());
+ pReq << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("client", "icq") << CHAR_PARAM("k", appId()) << INT_PARAM("ts", TS());
CalcHash(pReq);
pReq->m_szUrl.AppendChar('?');
pReq->m_szUrl += pReq->m_szParam; pReq->m_szParam.Empty();
diff --git a/protocols/ICQ-WIM/src/utils.cpp b/protocols/ICQ-WIM/src/utils.cpp
index b8d380f05d..1204cbfb53 100644
--- a/protocols/ICQ-WIM/src/utils.cpp
+++ b/protocols/ICQ-WIM/src/utils.cpp
@@ -286,6 +286,19 @@ int StatusFromString(const CMStringW &wszStatus)
return ID_STATUS_OFFLINE;
}
+int CIcqProto::StatusFromPresence(const JSONNode &presence, MCONTACT hContact)
+{
+ int iStatus = StatusFromString(presence["state"].as_mstring());
+
+ int iLastSeen = presence["lastseen"].as_int();
+ if (iLastSeen != 0)
+ setDword(hContact, DB_KEY_LASTSEEN, iLastSeen);
+ else if (getDword(hContact, DB_KEY_ONLINETS))
+ iStatus = ID_STATUS_ONLINE;
+
+ return iStatus;
+}
+
/////////////////////////////////////////////////////////////////////////////////////////
__int64 CIcqProto::getId(MCONTACT hContact, const char *szSetting)
diff --git a/protocols/ICQ-WIM/src/version.h b/protocols/ICQ-WIM/src/version.h
index 77882b494a..35a2dc3d6d 100644
--- a/protocols/ICQ-WIM/src/version.h
+++ b/protocols/ICQ-WIM/src/version.h
@@ -1,7 +1,7 @@
#define __MAJOR_VERSION 0
#define __MINOR_VERSION 96
#define __RELEASE_NUM 1
-#define __BUILD_NUM 3
+#define __BUILD_NUM 4
#include <stdver.h>