summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2020-04-16 20:27:26 +0300
committerGeorge Hazan <ghazan@miranda.im>2020-04-16 20:27:26 +0300
commit3b576fbd2dc5359c9c2e3b79633f77ec97d307c9 (patch)
treee1ee7ed1f19ea84342e3f6b827d14be7f2c2a63c
parenta1c32d8bf1118b20e9a701e2b6ac0300cf704e55 (diff)
SkypeWeb:
- fixes #2306 (SkypeWeb: sometimes plugin does not show contacts statuses); - obsoleted GetContactsInfoRequest removed (as well as its handler CSkypeProto::LoadContactsInfo); - major optimization for polling process; - ugly & crashy map Contacts removed; - old crappy timer code removed and replaced with CTimer; - version bump
-rw-r--r--protocols/SkypeWeb/src/requests/contacts.h15
-rw-r--r--protocols/SkypeWeb/src/requests/poll.h4
-rw-r--r--protocols/SkypeWeb/src/requests/status.h13
-rw-r--r--protocols/SkypeWeb/src/skype_avatars.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_chatrooms.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_contacts.cpp49
-rw-r--r--protocols/SkypeWeb/src/skype_dialogs.cpp13
-rw-r--r--protocols/SkypeWeb/src/skype_files.cpp4
-rw-r--r--protocols/SkypeWeb/src/skype_history_sync.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_login.cpp6
-rw-r--r--protocols/SkypeWeb/src/skype_messages.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_polling.cpp9
-rw-r--r--protocols/SkypeWeb/src/skype_proto.cpp20
-rw-r--r--protocols/SkypeWeb/src/skype_proto.h83
-rw-r--r--protocols/SkypeWeb/src/skype_timers.cpp51
-rw-r--r--protocols/SkypeWeb/src/skype_trouter.cpp57
-rw-r--r--protocols/SkypeWeb/src/skype_utils.cpp1
-rw-r--r--protocols/SkypeWeb/src/version.h2
18 files changed, 148 insertions, 187 deletions
diff --git a/protocols/SkypeWeb/src/requests/contacts.h b/protocols/SkypeWeb/src/requests/contacts.h
index 880e9c33d1..430b51aa2f 100644
--- a/protocols/SkypeWeb/src/requests/contacts.h
+++ b/protocols/SkypeWeb/src/requests/contacts.h
@@ -35,21 +35,6 @@ public:
}
};
-class GetContactsInfoRequest : public HttpRequest
-{
-public:
- GetContactsInfoRequest(CSkypeProto *ppro, const LIST<char> &skypenames, const char *skypename = "self") :
- HttpRequest(REQUEST_POST, FORMAT, "api.skype.com/users/%s/contacts/profiles", skypename)
- {
- Headers
- << CHAR_VALUE("X-Skypetoken", ppro->m_szApiToken)
- << CHAR_VALUE("Accept", "application/json");
-
- for (auto &it : skypenames)
- Body << CHAR_VALUE("contacts[]", it);
- }
-};
-
class GetContactsAuthRequest : public HttpRequest
{
public:
diff --git a/protocols/SkypeWeb/src/requests/poll.h b/protocols/SkypeWeb/src/requests/poll.h
index f0078c618a..7293c07067 100644
--- a/protocols/SkypeWeb/src/requests/poll.h
+++ b/protocols/SkypeWeb/src/requests/poll.h
@@ -25,6 +25,10 @@ public:
HttpRequest(REQUEST_POST, FORMAT, "%s/v1/users/ME/endpoints/SELF/subscriptions/0/poll", ppro->m_szServer)
{
timeout = 120000;
+
+ if (ppro->m_iPollingId != -1)
+ Url << INT_VALUE("ackId", ppro->m_iPollingId);
+
Headers
<< CHAR_VALUE("Referer", "https://web.skype.com/main")
<< CHAR_VALUE("Content-Type", "application/x-www-form-urlencoded")
diff --git a/protocols/SkypeWeb/src/requests/status.h b/protocols/SkypeWeb/src/requests/status.h
index 1000ebbccf..459b30471f 100644
--- a/protocols/SkypeWeb/src/requests/status.h
+++ b/protocols/SkypeWeb/src/requests/status.h
@@ -18,6 +18,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef _SKYPE_REQUEST_STATUS_H_
#define _SKYPE_REQUEST_STATUS_H_
+class GetStatusRequest : public HttpRequest
+{
+public:
+ GetStatusRequest(CSkypeProto *ppro) :
+ HttpRequest(REQUEST_GET, FORMAT, "%s/v1/users/ME/contacts/ALL/presenceDocs/messagingService", ppro->m_szServer)
+ {
+ Headers
+ << CHAR_VALUE("Accept", "application/json, text/javascript")
+ << FORMAT_VALUE("RegistrationToken", "registrationToken=%s", ppro->m_szToken.get())
+ << CHAR_VALUE("Content-Type", "application/json; charset=UTF-8");
+ }
+};
+
class SetStatusRequest : public HttpRequest
{
public:
diff --git a/protocols/SkypeWeb/src/skype_avatars.cpp b/protocols/SkypeWeb/src/skype_avatars.cpp
index b7e01445d5..ad4e9646d8 100644
--- a/protocols/SkypeWeb/src/skype_avatars.cpp
+++ b/protocols/SkypeWeb/src/skype_avatars.cpp
@@ -127,7 +127,7 @@ void CSkypeProto::GetAvatarFileName(MCONTACT hContact, wchar_t* pszDest, size_t
pszDest[tPathLen++] = '\\';
const wchar_t* szFileType = ProtoGetAvatarExtension(getByte(hContact, "AvatarType", PA_FORMAT_JPEG));
- CMStringA username(Contacts[hContact]);
+ CMStringA username(getId(hContact));
username.Replace("live:", "__live_");
username.Replace("facebook:", "__facebook_");
mir_snwprintf(pszDest + tPathLen, MAX_PATH - tPathLen, L"%S%s", username.c_str(), szFileType);
diff --git a/protocols/SkypeWeb/src/skype_chatrooms.cpp b/protocols/SkypeWeb/src/skype_chatrooms.cpp
index c11f15dc80..1a6ed3b71c 100644
--- a/protocols/SkypeWeb/src/skype_chatrooms.cpp
+++ b/protocols/SkypeWeb/src/skype_chatrooms.cpp
@@ -127,7 +127,7 @@ int CSkypeProto::OnGroupChatEventHook(WPARAM, LPARAM lParam)
MCONTACT hContact = dlg.m_hContact;
if (hContact != NULL)
- SendRequest(new InviteUserToChatRequest(chat_id, Contacts[hContact], "User", this));
+ SendRequest(new InviteUserToChatRequest(chat_id, getId(hContact), "User", this));
mir_cslock lck(m_InviteDialogsLock);
m_InviteDialogs.remove(&dlg);
diff --git a/protocols/SkypeWeb/src/skype_contacts.cpp b/protocols/SkypeWeb/src/skype_contacts.cpp
index a0b117a7f9..22f0b2185d 100644
--- a/protocols/SkypeWeb/src/skype_contacts.cpp
+++ b/protocols/SkypeWeb/src/skype_contacts.cpp
@@ -60,7 +60,7 @@ MCONTACT CSkypeProto::GetContactFromAuthEvent(MEVENT hEvent)
MCONTACT CSkypeProto::FindContact(const char *skypename)
{
for (auto &hContact : AccContacts())
- if (!mir_strcmpi(skypename, Contacts[hContact]))
+ if (!mir_strcmpi(skypename, getId(hContact)))
return hContact;
return 0;
@@ -124,24 +124,6 @@ void CSkypeProto::LoadContactsAuth(const NETLIBHTTPREQUEST *response)
}
}
-//[{"username":"echo123", "firstname" : "Echo \/ Sound Test Service", "lastname" : null, "avatarUrl" : null, "mood" : null, "richMood" : null, "displayname" : null, "country" : null, "city" : null},...]
-void CSkypeProto::LoadContactsInfo(const NETLIBHTTPREQUEST *response)
-{
- JsonReply root(response);
- if (root.error())
- return;
-
- for (auto &item : root.data()) {
- std::string skypename = item["username"].as_string();
- MCONTACT hContact = AddContact(skypename.c_str());
- if (hContact) {
- UpdateProfileCountry(item, hContact);
- UpdateProfileCity(item, hContact);
- UpdateProfileXStatusMessage(item, hContact);
- }
- }
-}
-
//[{"skypename":"echo123", "authorized" : true, "blocked" : false, ...},...]
// other properties is exists but empty
@@ -151,9 +133,9 @@ void CSkypeProto::LoadContactList(const NETLIBHTTPREQUEST *response)
if (reply.error())
return;
- auto &root = reply.data();
- LIST<char> skypenames(1);
bool loadAll = getBool("LoadAllContacts", false);
+
+ auto &root = reply.data();
for (auto &item : root["contacts"]) {
const JSONNode &name = item["name"];
@@ -213,25 +195,10 @@ void CSkypeProto::LoadContactList(const NETLIBHTTPREQUEST *response)
break;
}
}
-
- if (type == "skype")
- skypenames.insert(mir_strdup(skypename.c_str()));
}
}
}
- if (skypenames.getCount() > 0) {
- int i = 0;
- do {
- LIST<char> users(1);
- for (; i < skypenames.getCount() && users.getCount() <= 50; i++)
- users.insert(skypenames[i]);
- PushRequest(new GetContactsInfoRequest(this, users), &CSkypeProto::LoadContactsInfo);
- } while (i < skypenames.getCount());
-
- FreeList(skypenames);
- skypenames.destroy();
- }
PushRequest(new GetContactsAuthRequest(this), &CSkypeProto::LoadContactsAuth);
}
@@ -240,7 +207,7 @@ INT_PTR CSkypeProto::OnRequestAuth(WPARAM hContact, LPARAM)
if (hContact == INVALID_CONTACT_ID)
return 1;
- PushRequest(new AddContactRequest(this, Contacts[hContact]));
+ PushRequest(new AddContactRequest(this, getId(hContact)));
return 0;
}
@@ -249,7 +216,7 @@ INT_PTR CSkypeProto::OnGrantAuth(WPARAM hContact, LPARAM)
if (hContact == INVALID_CONTACT_ID)
return 1;
- PushRequest(new AuthAcceptRequest(this, Contacts[hContact]));
+ PushRequest(new AuthAcceptRequest(this, getId(hContact)));
return 0;
}
@@ -257,7 +224,7 @@ void CSkypeProto::OnContactDeleted(MCONTACT hContact)
{
if (IsOnline())
if (hContact && !isChatRoom(hContact))
- PushRequest(new DeleteContactRequest(this, Contacts[hContact]));
+ PushRequest(new DeleteContactRequest(this, getId(hContact)));
}
INT_PTR CSkypeProto::BlockContact(WPARAM hContact, LPARAM)
@@ -265,7 +232,7 @@ INT_PTR CSkypeProto::BlockContact(WPARAM hContact, LPARAM)
if (!IsOnline()) return 1;
if (IDYES == MessageBox(NULL, TranslateT("Are you sure?"), TranslateT("Warning"), MB_YESNO | MB_ICONQUESTION))
- SendRequest(new BlockContactRequest(this, Contacts[hContact]), &CSkypeProto::OnBlockContact, (void *)hContact);
+ SendRequest(new BlockContactRequest(this, getId(hContact)), &CSkypeProto::OnBlockContact, (void *)hContact);
return 0;
}
@@ -278,7 +245,7 @@ void CSkypeProto::OnBlockContact(const NETLIBHTTPREQUEST *response, void *p)
INT_PTR CSkypeProto::UnblockContact(WPARAM hContact, LPARAM)
{
- SendRequest(new UnblockContactRequest(this, Contacts[hContact]), &CSkypeProto::OnUnblockContact, (void *)hContact);
+ SendRequest(new UnblockContactRequest(this, getId(hContact)), &CSkypeProto::OnUnblockContact, (void *)hContact);
return 0;
}
diff --git a/protocols/SkypeWeb/src/skype_dialogs.cpp b/protocols/SkypeWeb/src/skype_dialogs.cpp
index 17f5f9bf4e..d0f3ba18a9 100644
--- a/protocols/SkypeWeb/src/skype_dialogs.cpp
+++ b/protocols/SkypeWeb/src/skype_dialogs.cpp
@@ -78,15 +78,10 @@ bool CSkypeGCCreateDlg::OnInitDialog()
void CSkypeGCCreateDlg::btnOk_OnOk(CCtrlButton*)
{
for (auto &hContact : m_proto->AccContacts()) {
- if (!m_proto->isChatRoom(hContact)) {
- if (HANDLE hItem = m_clc.FindContact(hContact)) {
- if (m_clc.GetCheck(hItem)) {
- char *szName = mir_strdup(m_proto->Contacts[hContact]);
- if (szName != nullptr)
- m_ContactsList.insert(szName);
- }
- }
- }
+ if (!m_proto->isChatRoom(hContact))
+ if (HANDLE hItem = m_clc.FindContact(hContact))
+ if (m_clc.GetCheck(hItem))
+ m_ContactsList.insert(m_proto->getId(hContact).Detach());
}
m_ContactsList.insert(m_proto->m_szSkypename.GetBuffer());
diff --git a/protocols/SkypeWeb/src/skype_files.cpp b/protocols/SkypeWeb/src/skype_files.cpp
index c6ad5743d7..d74dd71fe6 100644
--- a/protocols/SkypeWeb/src/skype_files.cpp
+++ b/protocols/SkypeWeb/src/skype_files.cpp
@@ -26,7 +26,7 @@ void CSkypeProto::SendFileThread(void *p)
ProtoBroadcastAck(fup->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, (HANDLE)fup);
T2Utf uszFileName(fup->tszFileName);
- SendRequest(new ASMObjectCreateRequest(this, CMStringA(FORMAT, "%d:%s", isChatRoom(fup->hContact) ? 19 : 8, Contacts[fup->hContact]), strrchr((const char*)uszFileName + 1, '\\')), &CSkypeProto::OnASMObjectCreated, fup);
+ SendRequest(new ASMObjectCreateRequest(this, CMStringA(FORMAT, "%d:%s", isChatRoom(fup->hContact) ? 19 : 8, getId(fup->hContact).c_str()), strrchr((const char*)uszFileName + 1, '\\')), &CSkypeProto::OnASMObjectCreated, fup);
}
void CSkypeProto::OnASMObjectCreated(const NETLIBHTTPREQUEST *response, void *arg)
@@ -105,7 +105,7 @@ void CSkypeProto::OnASMObjectUploaded(const NETLIBHTTPREQUEST *response, void *a
tinyxml2::XMLPrinter printer(0, true);
doc.Print(&printer);
- SendRequest(new SendMessageRequest(Contacts[fup->hContact], time(NULL), printer.CStr(), this, "RichText/Media_GenericFile"));
+ SendRequest(new SendMessageRequest(getId(fup->hContact), time(NULL), printer.CStr(), this, "RichText/Media_GenericFile"));
ProtoBroadcastAck(fup->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, (HANDLE)fup);
delete fup;
diff --git a/protocols/SkypeWeb/src/skype_history_sync.cpp b/protocols/SkypeWeb/src/skype_history_sync.cpp
index 7b31729bb4..f17d988f26 100644
--- a/protocols/SkypeWeb/src/skype_history_sync.cpp
+++ b/protocols/SkypeWeb/src/skype_history_sync.cpp
@@ -105,7 +105,7 @@ void CSkypeProto::OnGetServerHistory(const NETLIBHTTPREQUEST *response)
INT_PTR CSkypeProto::GetContactHistory(WPARAM hContact, LPARAM)
{
- PushRequest(new GetHistoryRequest(Contacts[hContact], 100, false, 0, this), &CSkypeProto::OnGetServerHistory);
+ PushRequest(new GetHistoryRequest(getId(hContact), 100, false, 0, this), &CSkypeProto::OnGetServerHistory);
return 0;
}
diff --git a/protocols/SkypeWeb/src/skype_login.cpp b/protocols/SkypeWeb/src/skype_login.cpp
index 262bc0a6b6..fda2187ca2 100644
--- a/protocols/SkypeWeb/src/skype_login.cpp
+++ b/protocols/SkypeWeb/src/skype_login.cpp
@@ -17,8 +17,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdafx.h"
-UINT_PTR CSkypeProto::m_timer;
-
void CSkypeProto::Login()
{
// login
@@ -113,6 +111,8 @@ void CSkypeProto::OnLoginSuccess()
m_szApiToken = getStringA("TokenSecret");
+ m_impl.m_heartBeat.StartSafe(600 * 1000);
+
SendRequest(new CreateEndpointRequest(this), &CSkypeProto::OnEndpointCreated);
}
@@ -178,6 +178,8 @@ void CSkypeProto::OnEndpointCreated(const NETLIBHTTPREQUEST *response)
return;
}
+ RefreshStatuses();
+
SendRequest(new CreateSubscriptionsRequest(this), &CSkypeProto::OnSubscriptionsCreated);
}
diff --git a/protocols/SkypeWeb/src/skype_messages.cpp b/protocols/SkypeWeb/src/skype_messages.cpp
index da1892bb18..166222998b 100644
--- a/protocols/SkypeWeb/src/skype_messages.cpp
+++ b/protocols/SkypeWeb/src/skype_messages.cpp
@@ -193,7 +193,7 @@ void CSkypeProto::MarkMessagesRead(MCONTACT hContact, MEVENT hDbEvent)
time_t timestamp = dbei.timestamp;
if (db_get_dw(hContact, m_szModuleName, "LastMsgTime", 0) > (timestamp - 300))
- PushRequest(new MarkMessageReadRequest(Contacts[hContact], timestamp, timestamp, false, this));
+ PushRequest(new MarkMessageReadRequest(getId(hContact), timestamp, timestamp, false, this));
}
void CSkypeProto::ProcessContactRecv(MCONTACT hContact, time_t timestamp, const char *szContent, const char *szMessageId)
diff --git a/protocols/SkypeWeb/src/skype_polling.cpp b/protocols/SkypeWeb/src/skype_polling.cpp
index 075b5085e8..c86f90dcd1 100644
--- a/protocols/SkypeWeb/src/skype_polling.cpp
+++ b/protocols/SkypeWeb/src/skype_polling.cpp
@@ -27,10 +27,10 @@ void CSkypeProto::PollingThread(void*)
break;
int nErrors = 0;
-
- PollRequest *request = new PollRequest(this);
+ m_iPollingId = -1;
while ((nErrors < POLLING_ERRORS_LIMIT) && m_iStatus != ID_STATUS_OFFLINE) {
+ std::unique_ptr<PollRequest> request(new PollRequest(this));
NLHR_PTR response(request->Send(m_hNetlibUser));
if (response == nullptr) {
nErrors++;
@@ -53,7 +53,6 @@ void CSkypeProto::PollingThread(void*)
}
}
}
- delete request;
if (m_iStatus != ID_STATUS_OFFLINE) {
debugLogA(__FUNCTION__ ": unexpected termination; switching protocol to offline");
@@ -73,6 +72,10 @@ void CSkypeProto::ParsePollData(const char *szData)
return;
for (auto &message : data["eventMessages"]) {
+ int eventId = message["id"].as_int();
+ if (eventId > m_iPollingId)
+ m_iPollingId = eventId;
+
const JSONNode &resType = message["resourceType"];
const JSONNode &resource = message["resource"];
diff --git a/protocols/SkypeWeb/src/skype_proto.cpp b/protocols/SkypeWeb/src/skype_proto.cpp
index 0db6e26836..84b7a1a337 100644
--- a/protocols/SkypeWeb/src/skype_proto.cpp
+++ b/protocols/SkypeWeb/src/skype_proto.cpp
@@ -26,7 +26,7 @@ CSkypeProto::CSkypeProto(const char* protoName, const wchar_t* userName) :
m_bThreadsTerminated(false),
m_TrouterConnection(nullptr),
m_opts(this),
- Contacts(this),
+ m_impl(*this),
m_szServer(mir_strdup(SKYPE_ENDPOINTS_HOST))
{
InitNetwork();
@@ -55,8 +55,6 @@ CSkypeProto::CSkypeProto(const char* protoName, const wchar_t* userName) :
g_plugin.addSound("skype_inc_call", L"SkypeWeb", LPGENW("Incoming call"));
g_plugin.addSound("skype_call_canceled", L"SkypeWeb", LPGENW("Incoming call canceled"));
- SkypeSetTimer();
-
m_hPollingThread = ForkThreadEx(&CSkypeProto::PollingThread, NULL, NULL);
m_hTrouterThread = ForkThreadEx(&CSkypeProto::TRouterThread, NULL, NULL);
}
@@ -78,8 +76,6 @@ CSkypeProto::~CSkypeProto()
WaitForSingleObject(m_hTrouterThread, INFINITE);
m_hTrouterThread = nullptr;
}
-
- SkypeUnsetTimer();
}
void CSkypeProto::OnModulesLoaded()
@@ -130,7 +126,7 @@ int CSkypeProto::SetAwayMsg(int, const wchar_t *msg)
HANDLE CSkypeProto::GetAwayMsg(MCONTACT hContact)
{
- PushRequest(new GetProfileRequest(this, Contacts[hContact]), [this, hContact](const NETLIBHTTPREQUEST *response) {
+ PushRequest(new GetProfileRequest(this, getId(hContact)), [this, hContact](const NETLIBHTTPREQUEST *response) {
JsonReply reply(response);
if (reply.error())
return;
@@ -190,7 +186,7 @@ int CSkypeProto::Authorize(MEVENT hDbEvent)
if (hContact == INVALID_CONTACT_ID)
return 1;
- PushRequest(new AuthAcceptRequest(this, Contacts[hContact]));
+ PushRequest(new AuthAcceptRequest(this, getId(hContact)));
return 0;
}
@@ -200,7 +196,7 @@ int CSkypeProto::AuthDeny(MEVENT hDbEvent, const wchar_t*)
if (hContact == INVALID_CONTACT_ID)
return 1;
- PushRequest(new AuthDeclineRequest(this, Contacts[hContact]));
+ PushRequest(new AuthDeclineRequest(this, getId(hContact)));
return 0;
}
@@ -214,7 +210,7 @@ int CSkypeProto::AuthRequest(MCONTACT hContact, const wchar_t *szMessage)
if (hContact == INVALID_CONTACT_ID)
return 1;
- PushRequest(new AddContactRequest(this, Contacts[hContact], T2Utf(szMessage)));
+ PushRequest(new AddContactRequest(this, getId(hContact), T2Utf(szMessage)));
return 0;
}
@@ -223,7 +219,7 @@ int CSkypeProto::GetInfo(MCONTACT hContact, int)
if (isChatRoom(hContact))
return 1;
- PushRequest(new GetProfileRequest(this, Contacts[hContact]), &CSkypeProto::LoadProfile, (void*)hContact);
+ PushRequest(new GetProfileRequest(this, getId(hContact)), &CSkypeProto::LoadProfile, (void*)hContact);
return 0;
}
@@ -269,6 +265,8 @@ int CSkypeProto::SetStatus(int iNewStatus)
CloseDialogs();
ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, ID_STATUS_OFFLINE);
+ m_impl.m_heartBeat.StopSafe();
+
if (!Miranda_IsTerminated())
setAllContactStatuses(ID_STATUS_OFFLINE, true);
return 0;
@@ -291,7 +289,7 @@ int CSkypeProto::SetStatus(int iNewStatus)
int CSkypeProto::UserIsTyping(MCONTACT hContact, int type)
{
- SendRequest(new SendTypingRequest(Contacts[hContact], type, this));
+ SendRequest(new SendTypingRequest(getId(hContact), type, this));
return 0;
}
diff --git a/protocols/SkypeWeb/src/skype_proto.h b/protocols/SkypeWeb/src/skype_proto.h
index e8d93e62a1..be5926d761 100644
--- a/protocols/SkypeWeb/src/skype_proto.h
+++ b/protocols/SkypeWeb/src/skype_proto.h
@@ -26,6 +26,25 @@ struct CSkypeProto : public PROTO < CSkypeProto >
friend CSkypeOptionsMain;
friend CSkypeGCCreateDlg;
+ class CSkypeProtoImpl
+ {
+ friend struct CSkypeProto;
+ CSkypeProto &m_proto;
+
+ CTimer m_heartBeat;
+ void OnHeartBeat(CTimer *)
+ {
+ m_proto.ProcessTimer();
+ }
+
+ CSkypeProtoImpl(CSkypeProto &pro) :
+ m_proto(pro),
+ m_heartBeat(Miranda_GetSystemWindow(), UINT_PTR(this) + 1)
+ {
+ m_heartBeat.OnEvent = Callback(this, &CSkypeProtoImpl::OnHeartBeat);
+ }
+ } m_impl;
+
public:
//////////////////////////////////////////////////////////////////////////////////////
@@ -85,42 +104,15 @@ public:
CSkypeOptions m_opts;
+ int m_iPollingId;
ptrA m_szApiToken, m_szToken, m_szId, m_szServer;
CMStringA m_szSkypename, m_szMyname;
-private:
- struct contacts_list
- {
- CSkypeProto *m_proto;
- std::map<MCONTACT, char*> m_cache;
-
- contacts_list(CSkypeProto *ppro) : m_proto(ppro)
- {}
-
- ~contacts_list()
- {
- for (auto &it : m_cache)
- mir_free(it.second);
- }
-
- const char* operator[](MCONTACT hContact)
- {
- try
- {
- return m_cache.at(hContact);
- }
- catch (std::out_of_range&)
- {
- char *id = m_proto->getStringA(hContact, SKYPE_SETTINGS_ID);
- m_cache[hContact] = id;
- return id;
- }
- }
-
- } Contacts;
-
- static UINT_PTR m_timer;
+ __forceinline CMStringA getId(MCONTACT hContact) {
+ return getMStringA(hContact, SKYPE_SETTINGS_ID);
+ }
+private:
class RequestQueue *requestQueue;
bool m_bHistorySynced;
@@ -147,8 +139,6 @@ private:
mir_cs messageSyncLock;
mir_cs m_StatusLock;
mir_cs m_AppendMessageLock;
- static mir_cs accountsLock;
- static mir_cs timerLock;
bool m_bThreadsTerminated;
@@ -220,6 +210,7 @@ private:
void OnSubscriptionsCreated(const NETLIBHTTPREQUEST *response);
void OnCapabilitiesSended(const NETLIBHTTPREQUEST *response);
void OnStatusChanged(const NETLIBHTTPREQUEST *response);
+ void OnReceiveStatus(const NETLIBHTTPREQUEST *response);
//TRouter
@@ -274,7 +265,6 @@ private:
MCONTACT GetContactFromAuthEvent(MEVENT hEvent);
void LoadContactsAuth(const NETLIBHTTPREQUEST *response);
- void LoadContactsInfo(const NETLIBHTTPREQUEST *response);
void LoadContactList(const NETLIBHTTPREQUEST *response);
void OnBlockContact(const NETLIBHTTPREQUEST *response, void *p);
@@ -328,13 +318,17 @@ private:
void SetChatStatus(MCONTACT hContact, int iStatus);
// polling
- void __cdecl PollingThread (void*);
- void __cdecl ParsePollData (const char*);
- void ProcessEndpointPresence (const JSONNode &node);
- void ProcessUserPresence (const JSONNode &node);
- void ProcessNewMessage (const JSONNode &node);
- void ProcessConversationUpdate (const JSONNode &node);
- void ProcessThreadUpdate (const JSONNode &node);
+ void __cdecl PollingThread(void*);
+
+ void ParsePollData(const char*);
+
+ void ProcessNewMessage(const JSONNode &node);
+ void ProcessUserPresence(const JSONNode &node);
+ void ProcessThreadUpdate(const JSONNode &node);
+ void ProcessEndpointPresence(const JSONNode &node);
+ void ProcessConversationUpdate(const JSONNode &node);
+
+ void RefreshStatuses(void);
// utils
template <typename T>
@@ -371,12 +365,7 @@ private:
static CMStringA UrlToSkypename(const char *url);
static CMStringA GetServerFromUrl(const char *url);
- //---Timers
- void CALLBACK SkypeUnsetTimer();
- void CALLBACK SkypeSetTimer();
void ProcessTimer();
- static void CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD);
- //---/
CMStringW RunConfirmationCode();
CMStringW ChangeTopicForm();
diff --git a/protocols/SkypeWeb/src/skype_timers.cpp b/protocols/SkypeWeb/src/skype_timers.cpp
deleted file mode 100644
index ec050dec4d..0000000000
--- a/protocols/SkypeWeb/src/skype_timers.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-Copyright (c) 2015-20 Miranda NG team (https://miranda-ng.org)
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation version 2
-of the License.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "stdafx.h"
-
-mir_cs CSkypeProto::timerLock;
-mir_cs CSkypeProto::accountsLock;
-
-void CSkypeProto::ProcessTimer()
-{
- if (IsOnline()) {
- PushRequest(new GetContactListRequest(this, nullptr), &CSkypeProto::LoadContactList);
- SendPresence(false);
- }
-}
-
-void CALLBACK CSkypeProto::TimerProc(HWND, UINT, UINT_PTR, DWORD)
-{
- mir_cslock lck(accountsLock);
- for (auto &it : CMPlugin::g_arInstances)
- it->ProcessTimer();
-}
-
-void CSkypeProto::SkypeSetTimer()
-{
- mir_cslock lck(timerLock);
- if (!m_timer)
- m_timer = SetTimer(nullptr, 0, 600000, TimerProc);
-}
-
-void CSkypeProto::SkypeUnsetTimer()
-{
- mir_cslock lck(timerLock);
- if (m_timer && CMPlugin::g_arInstances.getCount() == 0)
- KillTimer(nullptr, m_timer);
- m_timer = 0;
-}
diff --git a/protocols/SkypeWeb/src/skype_trouter.cpp b/protocols/SkypeWeb/src/skype_trouter.cpp
index cfc41f7b8c..79a4f12cf3 100644
--- a/protocols/SkypeWeb/src/skype_trouter.cpp
+++ b/protocols/SkypeWeb/src/skype_trouter.cpp
@@ -17,6 +17,63 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdafx.h"
+void CSkypeProto::ProcessTimer()
+{
+ if (!IsOnline())
+ return;
+
+ PushRequest(new GetContactListRequest(this, nullptr), &CSkypeProto::LoadContactList);
+ SendPresence(false);
+
+ RefreshStatuses();
+}
+
+void CSkypeProto::OnReceiveStatus(const NETLIBHTTPREQUEST *response)
+{
+ JsonReply reply(response);
+ if (reply.error())
+ return;
+
+ auto &root = reply.data();
+ for (auto &it : root["Responses"]) {
+ std::string id = it["Contact"].as_string();
+ id.erase(0, 2);
+ MCONTACT hContact = AddContact(id.c_str());
+ if (hContact) {
+ int status = SkypeToMirandaStatus(it["Payload"]["status"].as_string().c_str());
+ setWord(hContact, "Status", status);
+ }
+ }
+}
+
+void CSkypeProto::RefreshStatuses(void)
+{
+ int nRecs = 0;
+ GetStatusRequest *pReq = nullptr;
+
+ for (auto &it : AccContacts()) {
+ CMStringA id(getId(it));
+ if (id.IsEmpty())
+ continue;
+
+ if (pReq == nullptr) {
+ pReq = new GetStatusRequest(this);
+ nRecs = 0;
+ }
+
+ pReq->Url << CHAR_VALUE("cMri", "8:" + id);
+ nRecs++;
+
+ if (nRecs >= 10) {
+ PushRequest(pReq, &CSkypeProto::OnReceiveStatus);
+ pReq = nullptr;
+ }
+ }
+
+ if (pReq)
+ PushRequest(pReq, &CSkypeProto::OnReceiveStatus);
+}
+
void CSkypeProto::OnCreateTrouter(const NETLIBHTTPREQUEST *response)
{
JsonReply reply(response);
diff --git a/protocols/SkypeWeb/src/skype_utils.cpp b/protocols/SkypeWeb/src/skype_utils.cpp
index a3a1d3419f..cb27f1bab3 100644
--- a/protocols/SkypeWeb/src/skype_utils.cpp
+++ b/protocols/SkypeWeb/src/skype_utils.cpp
@@ -595,7 +595,6 @@ INT_PTR CSkypeProto::ParseSkypeUriService(WPARAM, LPARAM lParam)
INT_PTR CSkypeProto::GlobalParseSkypeUriService(WPARAM wParam, LPARAM lParam)
{
- mir_cslock lck(accountsLock);
for (auto &it : CMPlugin::g_arInstances)
if (it->IsOnline())
return it->ParseSkypeUriService(wParam, lParam);
diff --git a/protocols/SkypeWeb/src/version.h b/protocols/SkypeWeb/src/version.h
index f62177d12b..c2fb3727df 100644
--- a/protocols/SkypeWeb/src/version.h
+++ b/protocols/SkypeWeb/src/version.h
@@ -1,7 +1,7 @@
#define __MAJOR_VERSION 0
#define __MINOR_VERSION 12
#define __RELEASE_NUM 3
-#define __BUILD_NUM 6
+#define __BUILD_NUM 7
#include <stdver.h>