summaryrefslogtreecommitdiff
path: root/protocols/Icq10
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2018-12-24 22:11:02 +0300
committerGeorge Hazan <ghazan@miranda.im>2018-12-24 22:11:02 +0300
commit6e439e6cab64aaefc5220facac6df88cccef6cf7 (patch)
treee980249724bde79cd83fd4ca48f012cbc1d8594d /protocols/Icq10
parent47e705ac05b2572a687741af3a4141e560caf5d6 (diff)
Icq10: long poll thread implementation
Diffstat (limited to 'protocols/Icq10')
-rw-r--r--protocols/Icq10/src/proto.cpp8
-rw-r--r--protocols/Icq10/src/proto.h9
-rw-r--r--protocols/Icq10/src/server.cpp83
3 files changed, 86 insertions, 14 deletions
diff --git a/protocols/Icq10/src/proto.cpp b/protocols/Icq10/src/proto.cpp
index 95ac9478da..2bf99132f6 100644
--- a/protocols/Icq10/src/proto.cpp
+++ b/protocols/Icq10/src/proto.cpp
@@ -241,14 +241,6 @@ int CIcqProto::RecvContacts(MCONTACT hContact, PROTORECVEVENT* pre)
}
////////////////////////////////////////////////////////////////////////////////////////
-// RecvMsg
-
-MEVENT CIcqProto::RecvMsg(MCONTACT hContact, PROTORECVEVENT* pre)
-{
- return 0;
-}
-
-////////////////////////////////////////////////////////////////////////////////////////
// SendContacts
int CIcqProto::SendContacts(MCONTACT hContact, int, int nContacts, MCONTACT *hContactsList)
diff --git a/protocols/Icq10/src/proto.h b/protocols/Icq10/src/proto.h
index 82e65dcfcc..3239d4b7a1 100644
--- a/protocols/Icq10/src/proto.h
+++ b/protocols/Icq10/src/proto.h
@@ -62,7 +62,10 @@ class CIcqProto : public PROTO<CIcqProto>
void ProcessBuddyList(const JSONNode&);
void ProcessEvent(const JSONNode&);
+ void ProcessHistData(const JSONNode&);
void ProcessMyInfo(const JSONNode&);
+ void ProcessPresence(const JSONNode&);
+ void ProcessTyping(const JSONNode&);
HNETLIBCONN m_ConnPool[CONN_LAST];
CMStringA m_szSessionKey;
@@ -95,7 +98,10 @@ class CIcqProto : public PROTO<CIcqProto>
// threads
HANDLE m_hWorkerThread;
- void __cdecl ServerThread(void*);
+ void __cdecl ServerThread(void*);
+
+ HANDLE m_hPollThread;
+ void __cdecl PollThread(void*);
//////////////////////////////////////////////////////////////////////////////////////
// services
@@ -131,7 +137,6 @@ class CIcqProto : public PROTO<CIcqProto>
HWND CreateExtendedSearchUI(HWND owner) override;
int RecvContacts(MCONTACT hContact, PROTORECVEVENT*) override;
- MEVENT RecvMsg(MCONTACT hContact, PROTORECVEVENT*) override;
int SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT *hContactsList) override;
HANDLE SendFile(MCONTACT hContact, const wchar_t *szDescription, wchar_t **ppszFiles) override;
diff --git a/protocols/Icq10/src/server.cpp b/protocols/Icq10/src/server.cpp
index beb829fef7..3743e983a1 100644
--- a/protocols/Icq10/src/server.cpp
+++ b/protocols/Icq10/src/server.cpp
@@ -181,8 +181,7 @@ void CIcqProto::OnStartSession(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
for (auto &it : data["events"])
ProcessEvent(it);
- m_fetchBaseURL.Append("&first=1");
- Push(new AsyncHttpRequest(CONN_FETCH, REQUEST_GET, m_fetchBaseURL, &CIcqProto::OnFetchEvents));
+ m_hPollThread = ForkThreadEx(&CIcqProto::PollThread, 0, 0);
}
void CIcqProto::OnReceiveAvatar(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq)
@@ -275,9 +274,43 @@ void CIcqProto::ProcessEvent(const JSONNode &ev)
CMStringW szType = ev["type"].as_mstring();
if (szType == L"buddylist")
ProcessBuddyList(pData);
+ else if (szType == L"histDlgState")
+ ProcessHistData(pData);
else if (szType == L"myInfo")
ProcessMyInfo(pData);
+ else if (szType == L"presence")
+ ProcessPresence(pData);
+ else if (szType == L"typing")
+ ProcessTyping(pData);
+}
+
+void CIcqProto::ProcessHistData(const JSONNode &ev)
+{
+ DWORD dwUin = _wtol(ev["sn"].as_mstring());
+ IcqCacheItem *pCache = FindContactByUIN(dwUin);
+ if (pCache == nullptr)
+ return;
+
+ for (auto &it : ev["tail"]["messages"]) {
+ CMStringA msgId(it["msgId"].as_mstring());
+ CMStringW type(it["mediaType"].as_mstring());
+ if (type != "text")
+ continue;
+
+ MEVENT hDbEvent = db_event_getById(m_szModuleName, msgId);
+ if (hDbEvent == 0) {
+ bool bIsOutgoing = it["outgoing"].as_bool();
+ ptrA szUtf(mir_utf8encodeW(it["text"].as_mstring()));
+
+ PROTORECVEVENT pre = {};
+ pre.flags = (bIsOutgoing) ? PREF_SENT : 0;
+ pre.szMsgId = msgId;
+ pre.timestamp = it["time"].as_int();
+ pre.szMessage = szUtf;
+ ProtoChainRecvMsg(pCache->m_hContact, &pre);
+ }
+ }
}
void CIcqProto::ProcessMyInfo(const JSONNode &ev)
@@ -296,6 +329,30 @@ void CIcqProto::ProcessMyInfo(const JSONNode &ev)
}
}
+void CIcqProto::ProcessPresence(const JSONNode &ev)
+{
+ DWORD dwUin = _wtol(ev["aimId"].as_mstring());
+ int iStatus = StatusFromString(ev["state"].as_mstring());
+
+ IcqCacheItem *pCache = FindContactByUIN(dwUin);
+ if (pCache)
+ setDword(pCache->m_hContact, "Status", iStatus);
+}
+
+void CIcqProto::ProcessTyping(const JSONNode &ev)
+{
+ DWORD dwUin = _wtol(ev["aimId"].as_mstring());
+ CMStringW wszStatus = ev["typingStatus"].as_mstring();
+
+ IcqCacheItem *pCache = FindContactByUIN(dwUin);
+ if (pCache) {
+ if (wszStatus == "typing")
+ CallService(MS_PROTO_CONTACTISTYPING, pCache->m_hContact, 60);
+ else
+ CallService(MS_PROTO_CONTACTISTYPING, pCache->m_hContact, PROTOTYPE_CONTACTTYPING_OFF);
+ }
+}
+
void CIcqProto::OnFetchEvents(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
{
JsonReply root(pReply);
@@ -309,6 +366,24 @@ void CIcqProto::OnFetchEvents(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest*)
for (auto &it : data["events"])
ProcessEvent(it);
-
- Push(new AsyncHttpRequest(CONN_FETCH, REQUEST_GET, m_fetchBaseURL, &CIcqProto::OnFetchEvents));
}
+
+void __cdecl CIcqProto::PollThread(void*)
+{
+ debugLogA("Polling thread started");
+ bool bFirst = true;
+
+ while (!m_bTerminated) {
+ CMStringA szUrl = m_fetchBaseURL;
+ if (bFirst) {
+ bFirst = false;
+ szUrl.Append("&first=1");
+ }
+ else szUrl.Append("&timeout=60000");
+
+ ExecuteRequest(new AsyncHttpRequest(CONN_FETCH, REQUEST_GET, szUrl, &CIcqProto::OnFetchEvents));
+ }
+
+ debugLogA("Polling thread ended");
+ m_hPollThread = nullptr;
+} \ No newline at end of file