From ee58369830f5e7e07075952b24a64759cddd8faa Mon Sep 17 00:00:00 2001 From: George Hazan Date: Thu, 30 Nov 2023 20:27:45 +0300 Subject: =?UTF-8?q?fixes=20#3967=20(ICQ:=20=D0=BF=D0=B0=D1=80=D0=B0=D0=BC?= =?UTF-8?q?=D0=B5=D1=82=D1=80=20"=D0=92=20=D1=81=D0=B5=D1=82=D0=B8=20?= =?UTF-8?q?=D1=81"=20=D0=B1=D0=B5=D1=81=D0=BF=D0=BE=D0=BB=D0=B5=D0=B7?= =?UTF-8?q?=D0=B5=D0=BD)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- protocols/ICQ-WIM/src/poll.cpp | 2 ++ protocols/ICQ-WIM/src/proto.cpp | 50 ++------------------------------------ protocols/ICQ-WIM/src/proto.h | 18 ++++---------- protocols/ICQ-WIM/src/server.cpp | 30 ++++++++++++++++++----- protocols/ICQ-WIM/src/userinfo.cpp | 23 ++++++++++++++++++ protocols/ICQ-WIM/src/utils.cpp | 22 +++++++++-------- 6 files changed, 68 insertions(+), 77 deletions(-) (limited to 'protocols') diff --git a/protocols/ICQ-WIM/src/poll.cpp b/protocols/ICQ-WIM/src/poll.cpp index aee14bd00d..2af3be7348 100644 --- a/protocols/ICQ-WIM/src/poll.cpp +++ b/protocols/ICQ-WIM/src/poll.cpp @@ -50,6 +50,7 @@ void CIcqProto::ProcessBuddyList(const JSONNode &ev) if (hContact == INVALID_CONTACT_ID) continue; + ProcessOnline(buddy, hContact); setWString(hContact, "IcqGroup", pGroup->wszName); if (!bCreated) { @@ -111,6 +112,7 @@ void CIcqProto::ProcessDiff(const JSONNode &ev) if (hContact == INVALID_CONTACT_ID) continue; + ProcessOnline(buddy, hContact); setWString(hContact, "IcqGroup", pGroup->wszName); if (!bCreated) { diff --git a/protocols/ICQ-WIM/src/proto.cpp b/protocols/ICQ-WIM/src/proto.cpp index 0e07956cd5..cf5c5763e0 100644 --- a/protocols/ICQ-WIM/src/proto.cpp +++ b/protocols/ICQ-WIM/src/proto.cpp @@ -45,7 +45,6 @@ CIcqProto::CIcqProto(const char *aProtoName, const wchar_t *aUserName) : m_arOwnIds(1, PtrKeySortT), m_arCache(20, &CompareCache), m_arGroups(10, NumericKeySortT), - m_arLastSeenQueue(10, NumericKeySortT), m_arMarkReadQueue(10, NumericKeySortT), m_evRequestsQueue(CreateEvent(nullptr, FALSE, FALSE, nullptr)), m_szOwnId(this, DB_KEY_ID), @@ -336,53 +335,6 @@ INT_PTR CIcqProto::SvcGotoInbox(WPARAM, LPARAM) ///////////////////////////////////////////////////////////////////////////////////////// -void CIcqProto::OnLastSeen(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *) -{ - RobustReply root(pReply); - if (root.error() != 20000) - return; - - const JSONNode &results = root.results(); - for (auto &it : results["entries"]) { - if (auto *pUser = FindUser(it["sn"].as_mstring())) { - int iLastSeen = it["lastseen"].as_int(); - switch (iLastSeen) { - case 1388520000: // 01/01/2014, 00:00 GMT - setWString(pUser->m_hContact, DB_KEY_LASTSEEN, TranslateT("long time ago")); - ProcessStatus(pUser, ID_STATUS_OFFLINE); - break; - - case 0: - if (pUser->m_bWasOnline) { - ProcessStatus(pUser, ID_STATUS_ONLINE); - break; - } - __fallthrough; - - default: - setDword(pUser->m_hContact, DB_KEY_LASTSEEN, iLastSeen); - ProcessStatus(pUser, ID_STATUS_OFFLINE); - } - } - } -} - -void CIcqProto::SendLastSeen() -{ - mir_cslock lck(m_csLastSeenQueue); - - auto *pReq = new AsyncRapiRequest(this, "getUserLastseen", &CIcqProto::OnLastSeen); - JSONNode ids(JSON_ARRAY); ids.set_name("ids"); - for (auto &it: m_arLastSeenQueue) - ids << WCHAR_PARAM("", GetUserId(it->m_hContact)); - pReq->params.push_back(ids); - Push(pReq); - - m_arLastSeenQueue.destroy(); -} - -///////////////////////////////////////////////////////////////////////////////////////// - void CIcqProto::SendMarkRead() { mir_cslock lck(m_csMarkReadQueue); @@ -521,6 +473,8 @@ INT_PTR CIcqProto::GetCaps(int type, MCONTACT) int CIcqProto::GetInfo(MCONTACT hContact, int) { RetrieveUserInfo(hContact); + RetrievePresence(hContact); + if (Contact::IsGroupChat(hContact)) RetrieveChatInfo(hContact); return 0; diff --git a/protocols/ICQ-WIM/src/proto.h b/protocols/ICQ-WIM/src/proto.h index bdd47635c3..0919c3dad0 100644 --- a/protocols/ICQ-WIM/src/proto.h +++ b/protocols/ICQ-WIM/src/proto.h @@ -170,7 +170,7 @@ class CIcqProto : public PROTO friend class CIcqProto; CIcqProto &m_proto; - CTimer m_heartBeat, m_markRead, m_lastSeen; + CTimer m_heartBeat, m_markRead; void OnHeartBeat(CTimer *) { m_proto.CheckStatus(); @@ -181,19 +181,12 @@ class CIcqProto : public PROTO pTimer->Stop(); } - void OnLastSeen(CTimer *pTimer) { - m_proto.SendLastSeen(); - pTimer->Stop(); - } - CIcqProtoImpl(CIcqProto &pro) : m_proto(pro), m_markRead(Miranda_GetSystemWindow(), UINT_PTR(this)), - m_lastSeen(Miranda_GetSystemWindow(), UINT_PTR(this) + 1), - m_heartBeat(Miranda_GetSystemWindow(), UINT_PTR(this) + 2) + m_heartBeat(Miranda_GetSystemWindow(), UINT_PTR(this) + 1) { m_markRead.OnEvent = Callback(this, &CIcqProtoImpl::OnMarkRead); - m_lastSeen.OnEvent = Callback(this, &CIcqProtoImpl::OnLastSeen); m_heartBeat.OnEvent = Callback(this, &CIcqProtoImpl::OnHeartBeat); } } m_impl; @@ -218,6 +211,7 @@ class CIcqProto : public PROTO wchar_t* GetUIN(MCONTACT hContact); void MoveContactToGroup(MCONTACT hContact, const wchar_t *pwszGroup, const wchar_t *pwszNewGroup); bool RetrievePassword(); + void RetrievePresence(MCONTACT hContact); void RetrieveUserCaps(IcqUser *pUser); void RetrieveUserHistory(MCONTACT, __int64 startMsgId, bool bCreateRead); void RetrieveUserInfo(MCONTACT hContact); @@ -244,10 +238,6 @@ class CIcqProto : public PROTO LIST m_arMarkReadQueue; void SendMarkRead(); - mir_cs m_csLastSeenQueue; - LIST m_arLastSeenQueue; - void SendLastSeen(); - __int64 getId(MCONTACT hContact, const char *szSetting); void setId(MCONTACT hContact, const char *szSetting, __int64 iValue); @@ -266,6 +256,7 @@ class CIcqProto : public PROTO void OnGenToken(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); void OnGetChatInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); void OnGetPermitDeny(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); + void OnGePresence(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); void OnGetSticker(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); void OnGetUserCaps(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); void OnGetUserHistory(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq); @@ -289,6 +280,7 @@ class CIcqProto : public PROTO void ProcessImState(const JSONNode &pRoot); void ProcessMyInfo(const JSONNode &pRoot); void ProcessNotification(const JSONNode &pRoot); + void ProcessOnline(const JSONNode &presence, MCONTACT hContact); void ProcessPermissions(const JSONNode &pRoot); void ProcessPresence(const JSONNode &pRoot); void ProcessSessionEnd(const JSONNode &pRoot); diff --git a/protocols/ICQ-WIM/src/server.cpp b/protocols/ICQ-WIM/src/server.cpp index c27e1f4429..a03dfaddf0 100644 --- a/protocols/ICQ-WIM/src/server.cpp +++ b/protocols/ICQ-WIM/src/server.cpp @@ -417,12 +417,6 @@ MCONTACT CIcqProto::ParseBuddyInfo(const JSONNode &buddy, MCONTACT hContact, boo // we shall not remove existing phone number anyhow Json2string(hContact, buddy, "phoneNumber", DB_KEY_PHONE, true); - int onlineTime = buddy["onlineTime"].as_int(); - if (onlineTime) - setDword(hContact, DB_KEY_ONLINETS, time(0) - onlineTime); - else - delSetting(hContact, DB_KEY_ONLINETS); - Json2int(hContact, buddy, "official", "Official", bIsPartial); Json2int(hContact, buddy, "idleTime", "IdleTS", bIsPartial); @@ -717,6 +711,30 @@ void CIcqProto::RetrieveUserCaps(IcqUser *pUser) ///////////////////////////////////////////////////////////////////////////////////////// +void CIcqProto::OnGePresence(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq) +{ + JsonReply root(pReply); + if (root.error() != 200) + return; + + auto &data = root.data(); + for (auto &it : data["users"]) + ProcessOnline(it, pReq->hContact); +} + +void CIcqProto::RetrievePresence(MCONTACT hContact) +{ + CMStringW wszId(GetUserId(hContact)); + + auto *pReq = new AsyncHttpRequest(CONN_OLD, REQUEST_GET, "/presence/get", &CIcqProto::OnGePresence); + pReq->hContact = hContact; + pReq << CHAR_PARAM("a", m_szAToken) << CHAR_PARAM("f", "json") << CHAR_PARAM("k", appId()) << CHAR_PARAM("r", pReq->m_reqId) + << WCHAR_PARAM("t", wszId) << INT_PARAM("mdir", 1); + Push(pReq); +} + +///////////////////////////////////////////////////////////////////////////////////////// + void CIcqProto::OnGetUserInfo(NETLIBHTTPREQUEST *pReply, AsyncHttpRequest *pReq) { RobustReply root(pReply); diff --git a/protocols/ICQ-WIM/src/userinfo.cpp b/protocols/ICQ-WIM/src/userinfo.cpp index a48b2d0c58..b909c2ea5e 100644 --- a/protocols/ICQ-WIM/src/userinfo.cpp +++ b/protocols/ICQ-WIM/src/userinfo.cpp @@ -23,6 +23,7 @@ struct IcqUserInfoDlg : public CUserInfoPageDlg { CIcqProto *ppro; + HANDLE hEvent = 0; IcqUserInfoDlg(CIcqProto *_ppro) : CUserInfoPageDlg(g_plugin, IDD_INFO_ICQ), @@ -30,6 +31,28 @@ struct IcqUserInfoDlg : public CUserInfoPageDlg { } + bool OnInitDialog() override + { + hEvent = HookEventMessage(ME_DB_CONTACT_SETTINGCHANGED, m_hwnd, WM_USER); + return true; + } + + void OnDestroy() override + { + UnhookEvent(hEvent); + } + + UI_MESSAGE_MAP(IcqUserInfoDlg, CUserInfoPageDlg); + UI_MESSAGE(WM_USER, OnSettingChanged); + UI_MESSAGE_MAP_END(); + + LRESULT OnSettingChanged(UINT, WPARAM hContact, LPARAM) + { + if (hContact == m_hContact) + OnRefresh(); + return 0; + } + bool OnRefresh() override { SetDlgItemTextW(m_hwnd, IDC_UIN, ppro->GetUserId(m_hContact)); diff --git a/protocols/ICQ-WIM/src/utils.cpp b/protocols/ICQ-WIM/src/utils.cpp index 6db1050801..b6712ce8c9 100644 --- a/protocols/ICQ-WIM/src/utils.cpp +++ b/protocols/ICQ-WIM/src/utils.cpp @@ -167,6 +167,15 @@ bool IsValidType(const JSONNode &n) ///////////////////////////////////////////////////////////////////////////////////////// +void CIcqProto::ProcessOnline(const JSONNode &presence, MCONTACT hContact) +{ + int onlineTime = presence["onlineTime"].as_int(); + if (onlineTime) + setDword(hContact, DB_KEY_ONLINETS, time(0) - onlineTime); + else + delSetting(hContact, DB_KEY_ONLINETS); +} + int CIcqProto::StatusFromPresence(const JSONNode &presence, MCONTACT hContact) { auto *pUser = FindUser(GetUserId(hContact)); @@ -178,7 +187,6 @@ int CIcqProto::StatusFromPresence(const JSONNode &presence, MCONTACT hContact) if (wszStatus == L"online") { pUser->m_bWasOnline = true; iStatus = ID_STATUS_ONLINE; - setDword(hContact, DB_KEY_ONLINETS, time(0)); } else if (wszStatus == L"offline") iStatus = ID_STATUS_OFFLINE; @@ -201,16 +209,10 @@ int CIcqProto::StatusFromPresence(const JSONNode &presence, MCONTACT hContact) setDword(hContact, DB_KEY_LASTSEEN, iLastSeen); } else { - if (pUser->m_bWasOnline) { - iStatus = ID_STATUS_ONLINE; - setDword(hContact, DB_KEY_ONLINETS, time(0)); - } - else { - mir_cslock lck(m_csLastSeenQueue); - m_arLastSeenQueue.insert(pUser); - m_impl.m_lastSeen.Start(500); + if (!pUser->m_bWasOnline) return -1; - } + + iStatus = ID_STATUS_ONLINE; } return iStatus; -- cgit v1.2.3