diff options
author | dartraiden <wowemuh@gmail.com> | 2023-01-02 21:10:29 +0300 |
---|---|---|
committer | dartraiden <wowemuh@gmail.com> | 2023-01-02 21:10:29 +0300 |
commit | 1979fd80424d16b2e489f9b57d01d9c7811d25a2 (patch) | |
tree | 960d42c5fe4a51f0fe2850bea91256e226bce221 /protocols/SkypeWeb | |
parent | adfbbb217d4f4a05acf198755f219a5223d31c27 (diff) |
Update copyrights
Diffstat (limited to 'protocols/SkypeWeb')
41 files changed, 1416 insertions, 1416 deletions
diff --git a/protocols/SkypeWeb/src/main.cpp b/protocols/SkypeWeb/src/main.cpp index 3e3c36210b..b1e3ddfb5b 100644 --- a/protocols/SkypeWeb/src/main.cpp +++ b/protocols/SkypeWeb/src/main.cpp @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/request_queue.cpp b/protocols/SkypeWeb/src/request_queue.cpp index c7ab39d344..d6240e7cee 100644 --- a/protocols/SkypeWeb/src/request_queue.cpp +++ b/protocols/SkypeWeb/src/request_queue.cpp @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/requests/avatars.h b/protocols/SkypeWeb/src/requests/avatars.h index fd015e1bed..cdf5ac7b6e 100644 --- a/protocols/SkypeWeb/src/requests/avatars.h +++ b/protocols/SkypeWeb/src/requests/avatars.h @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/requests/capabilities.h b/protocols/SkypeWeb/src/requests/capabilities.h index 17b823a575..3170ca6d66 100644 --- a/protocols/SkypeWeb/src/requests/capabilities.h +++ b/protocols/SkypeWeb/src/requests/capabilities.h @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/requests/chatrooms.h b/protocols/SkypeWeb/src/requests/chatrooms.h index 2e12729862..2fc4e435ff 100644 --- a/protocols/SkypeWeb/src/requests/chatrooms.h +++ b/protocols/SkypeWeb/src/requests/chatrooms.h @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/requests/contacts.h b/protocols/SkypeWeb/src/requests/contacts.h index 4a62c67441..f9a3c13fa0 100644 --- a/protocols/SkypeWeb/src/requests/contacts.h +++ b/protocols/SkypeWeb/src/requests/contacts.h @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/requests/endpoint.h b/protocols/SkypeWeb/src/requests/endpoint.h index 8c351144c8..c0abe99a43 100644 --- a/protocols/SkypeWeb/src/requests/endpoint.h +++ b/protocols/SkypeWeb/src/requests/endpoint.h @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/requests/history.h b/protocols/SkypeWeb/src/requests/history.h index 75b7dc93d4..4438288479 100644 --- a/protocols/SkypeWeb/src/requests/history.h +++ b/protocols/SkypeWeb/src/requests/history.h @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/requests/login.h b/protocols/SkypeWeb/src/requests/login.h index e06cb28d40..e0053745d4 100644 --- a/protocols/SkypeWeb/src/requests/login.h +++ b/protocols/SkypeWeb/src/requests/login.h @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/requests/messages.h b/protocols/SkypeWeb/src/requests/messages.h index 4a71b79445..4e41e38dd4 100644 --- a/protocols/SkypeWeb/src/requests/messages.h +++ b/protocols/SkypeWeb/src/requests/messages.h @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/requests/oauth.h b/protocols/SkypeWeb/src/requests/oauth.h index 5d26982a8d..cc9842a0d2 100644 --- a/protocols/SkypeWeb/src/requests/oauth.h +++ b/protocols/SkypeWeb/src/requests/oauth.h @@ -1,74 +1,74 @@ -/* -Copyright (c) 2015-22 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/>. -*/ - -#ifndef _SKYPE_REQUEST_OAUTH_H_ -#define _SKYPE_REQUEST_OAUTH_H_ - -struct OAuthRequest : public AsyncHttpRequest -{ - OAuthRequest() : - AsyncHttpRequest(REQUEST_GET, HOST_OTHER, "https://login.live.com/login.srf", &CSkypeProto::OnOAuthStart) - { - flags |= NLHRF_REDIRECT; - - this << CHAR_PARAM("wa", "wsignin1.0") << CHAR_PARAM("wp", "MBI_SSL") - << CHAR_PARAM("wreply", "https://lw.skype.com/login/oauth/proxy?site_name=lw.skype.com") - << CHAR_PARAM("cobrandid", "90010"); - } - - OAuthRequest(const char *login, const char *password, const char *cookies, const char *ppft) : - AsyncHttpRequest(REQUEST_POST, HOST_OTHER, "https://login.live.com/ppsecure/post.srf", &CSkypeProto::OnOAuthConfirm) - { - this << CHAR_PARAM("wa", "wsignin1.0") << CHAR_PARAM("wp", "MBI_SSL") - << CHAR_PARAM("wreply", "https://lw.skype.com/login/oauth/proxy?site_name=lw.skype.com") - << CHAR_PARAM("cobrandid", "90010"); - m_szUrl.AppendFormat("?%s", m_szParam.c_str()); - m_szParam.Empty(); - - AddHeader("Cookie", cookies); - - if (auto *delim = strchr(login, ':')) - login = delim + 1; - - this << CHAR_PARAM("login", login) << CHAR_PARAM("passwd", password) << CHAR_PARAM("PPFT", ppft); - } - - OAuthRequest(const char *cookies, const char* ppft, const char* opid) : - AsyncHttpRequest(REQUEST_POST, HOST_OTHER, "https://login.live.com/ppsecure/post.srf", &CSkypeProto::OnOAuthAuthorize) - { - this << CHAR_PARAM("wa", "wsignin1.0") << CHAR_PARAM("wp", "MBI_SSL") - << CHAR_PARAM("wreply", "https://lw.skype.com/login/oauth/proxy?site_name=lw.skype.com") - << CHAR_PARAM("cobrandid", "90010") - << CHAR_PARAM("id", "293290") - << CHAR_PARAM("opid", opid); - - m_szUrl.AppendFormat("?%s", m_szParam.c_str()); - m_szParam.Empty(); - - AddHeader("Cookie", cookies); - - this << CHAR_PARAM("type", "28") << CHAR_PARAM("PPFT", ppft); - } - - OAuthRequest(const char *t) : - AsyncHttpRequest(REQUEST_POST, HOST_LOGIN, "/login/microsoft", &CSkypeProto::OnOAuthEnd) - { - this << CHAR_PARAM ("t", t) << CHAR_PARAM("site_name", "lw.skype.com") << INT_PARAM ("oauthPartner", 999); - } -}; - -#endif //_SKYPE_REQUEST_OAUTH_H_ +/*
+Copyright (c) 2015-23 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/>.
+*/
+
+#ifndef _SKYPE_REQUEST_OAUTH_H_
+#define _SKYPE_REQUEST_OAUTH_H_
+
+struct OAuthRequest : public AsyncHttpRequest
+{
+ OAuthRequest() :
+ AsyncHttpRequest(REQUEST_GET, HOST_OTHER, "https://login.live.com/login.srf", &CSkypeProto::OnOAuthStart)
+ {
+ flags |= NLHRF_REDIRECT;
+
+ this << CHAR_PARAM("wa", "wsignin1.0") << CHAR_PARAM("wp", "MBI_SSL")
+ << CHAR_PARAM("wreply", "https://lw.skype.com/login/oauth/proxy?site_name=lw.skype.com")
+ << CHAR_PARAM("cobrandid", "90010");
+ }
+
+ OAuthRequest(const char *login, const char *password, const char *cookies, const char *ppft) :
+ AsyncHttpRequest(REQUEST_POST, HOST_OTHER, "https://login.live.com/ppsecure/post.srf", &CSkypeProto::OnOAuthConfirm)
+ {
+ this << CHAR_PARAM("wa", "wsignin1.0") << CHAR_PARAM("wp", "MBI_SSL")
+ << CHAR_PARAM("wreply", "https://lw.skype.com/login/oauth/proxy?site_name=lw.skype.com")
+ << CHAR_PARAM("cobrandid", "90010");
+ m_szUrl.AppendFormat("?%s", m_szParam.c_str());
+ m_szParam.Empty();
+
+ AddHeader("Cookie", cookies);
+
+ if (auto *delim = strchr(login, ':'))
+ login = delim + 1;
+
+ this << CHAR_PARAM("login", login) << CHAR_PARAM("passwd", password) << CHAR_PARAM("PPFT", ppft);
+ }
+
+ OAuthRequest(const char *cookies, const char* ppft, const char* opid) :
+ AsyncHttpRequest(REQUEST_POST, HOST_OTHER, "https://login.live.com/ppsecure/post.srf", &CSkypeProto::OnOAuthAuthorize)
+ {
+ this << CHAR_PARAM("wa", "wsignin1.0") << CHAR_PARAM("wp", "MBI_SSL")
+ << CHAR_PARAM("wreply", "https://lw.skype.com/login/oauth/proxy?site_name=lw.skype.com")
+ << CHAR_PARAM("cobrandid", "90010")
+ << CHAR_PARAM("id", "293290")
+ << CHAR_PARAM("opid", opid);
+
+ m_szUrl.AppendFormat("?%s", m_szParam.c_str());
+ m_szParam.Empty();
+
+ AddHeader("Cookie", cookies);
+
+ this << CHAR_PARAM("type", "28") << CHAR_PARAM("PPFT", ppft);
+ }
+
+ OAuthRequest(const char *t) :
+ AsyncHttpRequest(REQUEST_POST, HOST_LOGIN, "/login/microsoft", &CSkypeProto::OnOAuthEnd)
+ {
+ this << CHAR_PARAM ("t", t) << CHAR_PARAM("site_name", "lw.skype.com") << INT_PARAM ("oauthPartner", 999);
+ }
+};
+
+#endif //_SKYPE_REQUEST_OAUTH_H_
diff --git a/protocols/SkypeWeb/src/requests/poll.h b/protocols/SkypeWeb/src/requests/poll.h index ce4b32cb4c..4475ec041e 100644 --- a/protocols/SkypeWeb/src/requests/poll.h +++ b/protocols/SkypeWeb/src/requests/poll.h @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/requests/profile.h b/protocols/SkypeWeb/src/requests/profile.h index 426087a63a..c255f9166b 100644 --- a/protocols/SkypeWeb/src/requests/profile.h +++ b/protocols/SkypeWeb/src/requests/profile.h @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/requests/search.h b/protocols/SkypeWeb/src/requests/search.h index d47562ff9c..357ad470bc 100644 --- a/protocols/SkypeWeb/src/requests/search.h +++ b/protocols/SkypeWeb/src/requests/search.h @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/requests/status.h b/protocols/SkypeWeb/src/requests/status.h index 58ebd23dcd..74e35960cd 100644 --- a/protocols/SkypeWeb/src/requests/status.h +++ b/protocols/SkypeWeb/src/requests/status.h @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/requests/subscriptions.h b/protocols/SkypeWeb/src/requests/subscriptions.h index b0f71046e8..b1ddc03a6e 100644 --- a/protocols/SkypeWeb/src/requests/subscriptions.h +++ b/protocols/SkypeWeb/src/requests/subscriptions.h @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/skype_avatars.cpp b/protocols/SkypeWeb/src/skype_avatars.cpp index 934180e929..1ac07d6d33 100644 --- a/protocols/SkypeWeb/src/skype_avatars.cpp +++ b/protocols/SkypeWeb/src/skype_avatars.cpp @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/skype_chatrooms.cpp b/protocols/SkypeWeb/src/skype_chatrooms.cpp index 3087321ea2..4f27b13c5c 100644 --- a/protocols/SkypeWeb/src/skype_chatrooms.cpp +++ b/protocols/SkypeWeb/src/skype_chatrooms.cpp @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/skype_contacts.cpp b/protocols/SkypeWeb/src/skype_contacts.cpp index cd1a2a13a1..75827daaf6 100644 --- a/protocols/SkypeWeb/src/skype_contacts.cpp +++ b/protocols/SkypeWeb/src/skype_contacts.cpp @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/skype_db.cpp b/protocols/SkypeWeb/src/skype_db.cpp index 3417b15c01..8d815088d1 100644 --- a/protocols/SkypeWeb/src/skype_db.cpp +++ b/protocols/SkypeWeb/src/skype_db.cpp @@ -1,119 +1,119 @@ -/* -Copyright (c) 2015-22 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" - -struct { int type; char *name; uint32_t flags; } g_SkypeDBTypes[] = -{ - { SKYPE_DB_EVENT_TYPE_INCOMING_CALL, LPGEN("Incoming call"), DETF_NONOTIFY }, - { SKYPE_DB_EVENT_TYPE_EDITED_MESSAGE, LPGEN("Edited message"), 0 }, - { SKYPE_DB_EVENT_TYPE_ACTION, LPGEN("Action"), 0 }, - { SKYPE_DB_EVENT_TYPE_CALL_INFO, LPGEN("Call information"), 0 }, - { SKYPE_DB_EVENT_TYPE_FILETRANSFER_INFO, LPGEN("File transfer information"), 0 }, - { SKYPE_DB_EVENT_TYPE_URIOBJ, LPGEN("URI object"), 0 }, - { SKYPE_DB_EVENT_TYPE_MOJI, LPGEN("Moji"), 0 }, - { SKYPE_DB_EVENT_TYPE_FILE, LPGEN("File"), 0 }, - { SKYPE_DB_EVENT_TYPE_UNKNOWN, LPGEN("Unknown event"), 0 }, -}; - -MEVENT CSkypeProto::GetMessageFromDb(const char *messageId) -{ - if (messageId == nullptr) - return NULL; - - return db_event_getById(m_szModuleName, messageId); -} - -MEVENT CSkypeProto::AddDbEvent(uint16_t type, MCONTACT hContact, uint32_t timestamp, uint32_t flags, const CMStringW &content, const CMStringA &msgId) -{ - if (MEVENT hDbEvent = GetMessageFromDb(msgId)) - return hDbEvent; - - T2Utf szMsg(content); - DBEVENTINFO dbei = {}; - dbei.szModule = m_szModuleName; - dbei.timestamp = timestamp; - dbei.eventType = type; - dbei.cbBlob = (uint32_t)mir_strlen(szMsg) + 1; - dbei.pBlob = (uint8_t *)szMsg; - dbei.flags = flags; - dbei.szId = msgId; - return db_event_add(hContact, &dbei); -} - -void CSkypeProto::EditEvent(MCONTACT hContact, MEVENT hEvent, const CMStringW &szContent, time_t edit_time) -{ - mir_cslock lck(m_AppendMessageLock); - - DB::EventInfo dbei; - dbei.cbBlob = -1; - if (db_event_get(hEvent, &dbei)) - return; - - JSONNode jMsg = JSONNode::parse((char*)dbei.pBlob); - if (jMsg) { - JSONNode &jEdits = jMsg["edits"]; - if (jEdits) { - for (auto &it : jEdits) - if (it["time"].as_int() == edit_time) - return; - - JSONNode jEdit; - jEdit << INT_PARAM("time", (long)edit_time) << WCHAR_PARAM("text", szContent); - jEdits << jEdit; - } - } - else { - JSONNode jOriginalMsg; jOriginalMsg.set_name("original_message"); - jOriginalMsg << INT_PARAM("time", (long)dbei.timestamp) << CHAR_PARAM("text", (char *)dbei.pBlob); - - jMsg = JSONNode(); - jMsg << jOriginalMsg; - - JSONNode jEdit; - jEdit << INT_PARAM("time", (long)edit_time) << WCHAR_PARAM("text", szContent); - - JSONNode jEdits(JSON_ARRAY); jEdits.set_name("edits"); - jEdits << jEdit; - jMsg << jEdits; - } - - std::string newMsg = jMsg.write().c_str(); - dbei.cbBlob = int(newMsg.size() + 1); - dbei.pBlob = (uint8_t*)newMsg.c_str(); - db_event_edit(hContact, hEvent, &dbei); -} - -void CSkypeProto::InitDBEvents() -{ - // custom event - DBEVENTTYPEDESCR dbEventType = {}; - dbEventType.module = m_szModuleName; - dbEventType.flags = DETF_HISTORY | DETF_MSGWINDOW; - dbEventType.iconService = MODULE "/GetEventIcon"; - dbEventType.textService = MODULE "/GetEventText"; - - for (auto &cur : g_SkypeDBTypes) { - dbEventType.eventType = cur.type; - dbEventType.descr = Translate(cur.name); - dbEventType.flags |= cur.flags; - - DbEvent_RegisterType(&dbEventType); - - dbEventType.flags &= (~cur.flags); - } -} +/*
+Copyright (c) 2015-23 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"
+
+struct { int type; char *name; uint32_t flags; } g_SkypeDBTypes[] =
+{
+ { SKYPE_DB_EVENT_TYPE_INCOMING_CALL, LPGEN("Incoming call"), DETF_NONOTIFY },
+ { SKYPE_DB_EVENT_TYPE_EDITED_MESSAGE, LPGEN("Edited message"), 0 },
+ { SKYPE_DB_EVENT_TYPE_ACTION, LPGEN("Action"), 0 },
+ { SKYPE_DB_EVENT_TYPE_CALL_INFO, LPGEN("Call information"), 0 },
+ { SKYPE_DB_EVENT_TYPE_FILETRANSFER_INFO, LPGEN("File transfer information"), 0 },
+ { SKYPE_DB_EVENT_TYPE_URIOBJ, LPGEN("URI object"), 0 },
+ { SKYPE_DB_EVENT_TYPE_MOJI, LPGEN("Moji"), 0 },
+ { SKYPE_DB_EVENT_TYPE_FILE, LPGEN("File"), 0 },
+ { SKYPE_DB_EVENT_TYPE_UNKNOWN, LPGEN("Unknown event"), 0 },
+};
+
+MEVENT CSkypeProto::GetMessageFromDb(const char *messageId)
+{
+ if (messageId == nullptr)
+ return NULL;
+
+ return db_event_getById(m_szModuleName, messageId);
+}
+
+MEVENT CSkypeProto::AddDbEvent(uint16_t type, MCONTACT hContact, uint32_t timestamp, uint32_t flags, const CMStringW &content, const CMStringA &msgId)
+{
+ if (MEVENT hDbEvent = GetMessageFromDb(msgId))
+ return hDbEvent;
+
+ T2Utf szMsg(content);
+ DBEVENTINFO dbei = {};
+ dbei.szModule = m_szModuleName;
+ dbei.timestamp = timestamp;
+ dbei.eventType = type;
+ dbei.cbBlob = (uint32_t)mir_strlen(szMsg) + 1;
+ dbei.pBlob = (uint8_t *)szMsg;
+ dbei.flags = flags;
+ dbei.szId = msgId;
+ return db_event_add(hContact, &dbei);
+}
+
+void CSkypeProto::EditEvent(MCONTACT hContact, MEVENT hEvent, const CMStringW &szContent, time_t edit_time)
+{
+ mir_cslock lck(m_AppendMessageLock);
+
+ DB::EventInfo dbei;
+ dbei.cbBlob = -1;
+ if (db_event_get(hEvent, &dbei))
+ return;
+
+ JSONNode jMsg = JSONNode::parse((char*)dbei.pBlob);
+ if (jMsg) {
+ JSONNode &jEdits = jMsg["edits"];
+ if (jEdits) {
+ for (auto &it : jEdits)
+ if (it["time"].as_int() == edit_time)
+ return;
+
+ JSONNode jEdit;
+ jEdit << INT_PARAM("time", (long)edit_time) << WCHAR_PARAM("text", szContent);
+ jEdits << jEdit;
+ }
+ }
+ else {
+ JSONNode jOriginalMsg; jOriginalMsg.set_name("original_message");
+ jOriginalMsg << INT_PARAM("time", (long)dbei.timestamp) << CHAR_PARAM("text", (char *)dbei.pBlob);
+
+ jMsg = JSONNode();
+ jMsg << jOriginalMsg;
+
+ JSONNode jEdit;
+ jEdit << INT_PARAM("time", (long)edit_time) << WCHAR_PARAM("text", szContent);
+
+ JSONNode jEdits(JSON_ARRAY); jEdits.set_name("edits");
+ jEdits << jEdit;
+ jMsg << jEdits;
+ }
+
+ std::string newMsg = jMsg.write().c_str();
+ dbei.cbBlob = int(newMsg.size() + 1);
+ dbei.pBlob = (uint8_t*)newMsg.c_str();
+ db_event_edit(hContact, hEvent, &dbei);
+}
+
+void CSkypeProto::InitDBEvents()
+{
+ // custom event
+ DBEVENTTYPEDESCR dbEventType = {};
+ dbEventType.module = m_szModuleName;
+ dbEventType.flags = DETF_HISTORY | DETF_MSGWINDOW;
+ dbEventType.iconService = MODULE "/GetEventIcon";
+ dbEventType.textService = MODULE "/GetEventText";
+
+ for (auto &cur : g_SkypeDBTypes) {
+ dbEventType.eventType = cur.type;
+ dbEventType.descr = Translate(cur.name);
+ dbEventType.flags |= cur.flags;
+
+ DbEvent_RegisterType(&dbEventType);
+
+ dbEventType.flags &= (~cur.flags);
+ }
+}
diff --git a/protocols/SkypeWeb/src/skype_db.h b/protocols/SkypeWeb/src/skype_db.h index 8a0d58a049..ad9a7e2ff7 100644 --- a/protocols/SkypeWeb/src/skype_db.h +++ b/protocols/SkypeWeb/src/skype_db.h @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/skype_events.cpp b/protocols/SkypeWeb/src/skype_events.cpp index a2f13e8187..49a93a53a0 100644 --- a/protocols/SkypeWeb/src/skype_events.cpp +++ b/protocols/SkypeWeb/src/skype_events.cpp @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/skype_history_sync.cpp b/protocols/SkypeWeb/src/skype_history_sync.cpp index a034722bbd..ae72cdb920 100644 --- a/protocols/SkypeWeb/src/skype_history_sync.cpp +++ b/protocols/SkypeWeb/src/skype_history_sync.cpp @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/skype_icons.cpp b/protocols/SkypeWeb/src/skype_icons.cpp index 8bd77f324a..15934a3d23 100644 --- a/protocols/SkypeWeb/src/skype_icons.cpp +++ b/protocols/SkypeWeb/src/skype_icons.cpp @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/skype_login.cpp b/protocols/SkypeWeb/src/skype_login.cpp index d003c4ee71..94faff30d8 100644 --- a/protocols/SkypeWeb/src/skype_login.cpp +++ b/protocols/SkypeWeb/src/skype_login.cpp @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/skype_menus.cpp b/protocols/SkypeWeb/src/skype_menus.cpp index 2d52b1a790..faf99da486 100644 --- a/protocols/SkypeWeb/src/skype_menus.cpp +++ b/protocols/SkypeWeb/src/skype_menus.cpp @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/skype_menus.h b/protocols/SkypeWeb/src/skype_menus.h index 3e8c380d6f..b4e74aa6a3 100644 --- a/protocols/SkypeWeb/src/skype_menus.h +++ b/protocols/SkypeWeb/src/skype_menus.h @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/skype_messages.cpp b/protocols/SkypeWeb/src/skype_messages.cpp index c6974a071c..01a0235caa 100644 --- a/protocols/SkypeWeb/src/skype_messages.cpp +++ b/protocols/SkypeWeb/src/skype_messages.cpp @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/skype_oauth.cpp b/protocols/SkypeWeb/src/skype_oauth.cpp index dee5e92387..0a1f8908d3 100644 --- a/protocols/SkypeWeb/src/skype_oauth.cpp +++ b/protocols/SkypeWeb/src/skype_oauth.cpp @@ -1,165 +1,165 @@ -/* -Copyright (c) 2015-22 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" - -static std::string sub(const std::string &str, const char *start, const char *end) -{ - size_t i1 = str.find(start); - if (i1 == -1) - return ""; - - i1 += strlen(start); - size_t i2 = str.find(end, i1); - return (i2 == -1) ? "" : str.substr(i1, i2 - i1); -} - -void CSkypeProto::OnOAuthStart(NETLIBHTTPREQUEST *response, AsyncHttpRequest*) -{ - if (response == nullptr || response->pData == nullptr) { - ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN); - SetStatus(ID_STATUS_OFFLINE); - return; - } - - std::regex regex; - std::smatch match; - std::string content = response->pData; - - regex = "<input.+?type=\"hidden\".+?name=\"PPFT\".+?id=\"i0327\".+?value=\"(.+?)\".*?/>"; - - if (!std::regex_search(content, match, regex)) { - ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN); - SetStatus(ID_STATUS_OFFLINE); - return; - } - std::string PPFT = match[1]; - - std::map<std::string, std::string> scookies; - regex = "^(.+?)=(.*?);"; - - for (int i = 0; i < response->headersCount; i++) { - if (mir_strcmpi(response->headers[i].szName, "Set-Cookie")) - continue; - - content = response->headers[i].szValue; - if (std::regex_search(content, match, regex)) - scookies[match[1]] = match[2]; - } - - ptrA login(getStringA(SKYPE_SETTINGS_ID)); - ptrA password(getStringA(SKYPE_SETTINGS_PASSWORD)); - CMStringA mscookies(FORMAT, "MSPRequ=%s;MSPOK=%s;CkTst=G%lld;", scookies["MSPRequ"].c_str(), scookies["MSPOK"].c_str(), time(NULL)); - - cookies["MSPRequ"] = scookies["MSPRequ"]; - - PushRequest(new OAuthRequest(login, password, mscookies.c_str(), PPFT.c_str())); -} - -bool CSkypeProto::CheckOauth(const char *szResponse) -{ - std::string content = szResponse; - std::smatch match; - if (!std::regex_search(content, match, std::regex("<input.+?type=\"hidden\".+?name=\"t\".+?id=\"t\".+?value=\"(.+?)\".*?>"))) - if (!std::regex_search(content, match, std::regex("<input.+?type=\"hidden\".+?name=\"ipt\".+?id=\"ipt\".+?value=\"(.+?)\".*?>"))) - return false; - - std::string t = match[1]; - PushRequest(new OAuthRequest(t.c_str())); - return true; -} - -void CSkypeProto::OnOAuthConfirm(NETLIBHTTPREQUEST *response, AsyncHttpRequest *) -{ - if (response == nullptr || response->pData == nullptr) { - ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN); - SetStatus(ID_STATUS_OFFLINE); - return; - } - - if (CheckOauth(response->pData)) - return; - - std::string content = response->pData; - std::string PPFT = sub(content, "sFT:'", "'"); - std::string opid = sub(content, "opid=", "&"); - if (PPFT.empty() || opid.empty()) { - ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN); - SetStatus(ID_STATUS_OFFLINE); - return; - } - - std::regex regex("^(.+?=.*?;)"); - std::smatch match; - CMStringA mscookies; - - for (int i = 0; i < response->headersCount; i++) { - if (mir_strcmpi(response->headers[i].szName, "Set-Cookie")) - continue; - - content = response->headers[i].szValue; - if (std::regex_search(content, match, regex)) - mscookies.Append(match[1].str().c_str()); - } - - PushRequest(new OAuthRequest(mscookies.c_str(), PPFT.c_str(), opid.c_str())); -} - -void CSkypeProto::OnOAuthAuthorize(NETLIBHTTPREQUEST *response, AsyncHttpRequest*) -{ - if (response == nullptr || response->pData == nullptr) { - ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN); - SetStatus(ID_STATUS_OFFLINE); - return; - } - - if (!CheckOauth(response->pData)) { - ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN); - SetStatus(ID_STATUS_OFFLINE); - } -} - -void CSkypeProto::OnOAuthEnd(NETLIBHTTPREQUEST *response, AsyncHttpRequest*) -{ - if (response == nullptr || response->pData == nullptr) { - ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN); - SetStatus(ID_STATUS_OFFLINE); - return; - } - - std::regex regex; - std::smatch match; - std::string content = response->pData; - - regex = "<input.+?type=\"hidden\".+?name=\"skypetoken\".+?value=\"(.+?)\".*?/>"; - if (!std::regex_search(content, match, regex)) { - ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN); - SetStatus(ID_STATUS_OFFLINE); - return; - } - std::string token = match[1]; - setString("TokenSecret", token.c_str()); - regex = "<input.+?type=\"hidden\".+?name=\"expires_in\".+?value=\"(.+?)\".*?/>"; - - if (std::regex_search(content, match, regex)) { - std::string expiresIn = match[1]; - int seconds = atoi(expiresIn.c_str()); - setDword("TokenExpiresIn", time(NULL) + seconds); - } - - OnLoginSuccess(); -} +/*
+Copyright (c) 2015-23 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"
+
+static std::string sub(const std::string &str, const char *start, const char *end)
+{
+ size_t i1 = str.find(start);
+ if (i1 == -1)
+ return "";
+
+ i1 += strlen(start);
+ size_t i2 = str.find(end, i1);
+ return (i2 == -1) ? "" : str.substr(i1, i2 - i1);
+}
+
+void CSkypeProto::OnOAuthStart(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
+{
+ if (response == nullptr || response->pData == nullptr) {
+ ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+
+ std::regex regex;
+ std::smatch match;
+ std::string content = response->pData;
+
+ regex = "<input.+?type=\"hidden\".+?name=\"PPFT\".+?id=\"i0327\".+?value=\"(.+?)\".*?/>";
+
+ if (!std::regex_search(content, match, regex)) {
+ ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+ std::string PPFT = match[1];
+
+ std::map<std::string, std::string> scookies;
+ regex = "^(.+?)=(.*?);";
+
+ for (int i = 0; i < response->headersCount; i++) {
+ if (mir_strcmpi(response->headers[i].szName, "Set-Cookie"))
+ continue;
+
+ content = response->headers[i].szValue;
+ if (std::regex_search(content, match, regex))
+ scookies[match[1]] = match[2];
+ }
+
+ ptrA login(getStringA(SKYPE_SETTINGS_ID));
+ ptrA password(getStringA(SKYPE_SETTINGS_PASSWORD));
+ CMStringA mscookies(FORMAT, "MSPRequ=%s;MSPOK=%s;CkTst=G%lld;", scookies["MSPRequ"].c_str(), scookies["MSPOK"].c_str(), time(NULL));
+
+ cookies["MSPRequ"] = scookies["MSPRequ"];
+
+ PushRequest(new OAuthRequest(login, password, mscookies.c_str(), PPFT.c_str()));
+}
+
+bool CSkypeProto::CheckOauth(const char *szResponse)
+{
+ std::string content = szResponse;
+ std::smatch match;
+ if (!std::regex_search(content, match, std::regex("<input.+?type=\"hidden\".+?name=\"t\".+?id=\"t\".+?value=\"(.+?)\".*?>")))
+ if (!std::regex_search(content, match, std::regex("<input.+?type=\"hidden\".+?name=\"ipt\".+?id=\"ipt\".+?value=\"(.+?)\".*?>")))
+ return false;
+
+ std::string t = match[1];
+ PushRequest(new OAuthRequest(t.c_str()));
+ return true;
+}
+
+void CSkypeProto::OnOAuthConfirm(NETLIBHTTPREQUEST *response, AsyncHttpRequest *)
+{
+ if (response == nullptr || response->pData == nullptr) {
+ ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+
+ if (CheckOauth(response->pData))
+ return;
+
+ std::string content = response->pData;
+ std::string PPFT = sub(content, "sFT:'", "'");
+ std::string opid = sub(content, "opid=", "&");
+ if (PPFT.empty() || opid.empty()) {
+ ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+
+ std::regex regex("^(.+?=.*?;)");
+ std::smatch match;
+ CMStringA mscookies;
+
+ for (int i = 0; i < response->headersCount; i++) {
+ if (mir_strcmpi(response->headers[i].szName, "Set-Cookie"))
+ continue;
+
+ content = response->headers[i].szValue;
+ if (std::regex_search(content, match, regex))
+ mscookies.Append(match[1].str().c_str());
+ }
+
+ PushRequest(new OAuthRequest(mscookies.c_str(), PPFT.c_str(), opid.c_str()));
+}
+
+void CSkypeProto::OnOAuthAuthorize(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
+{
+ if (response == nullptr || response->pData == nullptr) {
+ ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+
+ if (!CheckOauth(response->pData)) {
+ ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
+ SetStatus(ID_STATUS_OFFLINE);
+ }
+}
+
+void CSkypeProto::OnOAuthEnd(NETLIBHTTPREQUEST *response, AsyncHttpRequest*)
+{
+ if (response == nullptr || response->pData == nullptr) {
+ ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+
+ std::regex regex;
+ std::smatch match;
+ std::string content = response->pData;
+
+ regex = "<input.+?type=\"hidden\".+?name=\"skypetoken\".+?value=\"(.+?)\".*?/>";
+ if (!std::regex_search(content, match, regex)) {
+ ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, NULL, LOGIN_ERROR_UNKNOWN);
+ SetStatus(ID_STATUS_OFFLINE);
+ return;
+ }
+ std::string token = match[1];
+ setString("TokenSecret", token.c_str());
+ regex = "<input.+?type=\"hidden\".+?name=\"expires_in\".+?value=\"(.+?)\".*?/>";
+
+ if (std::regex_search(content, match, regex)) {
+ std::string expiresIn = match[1];
+ int seconds = atoi(expiresIn.c_str());
+ setDword("TokenExpiresIn", time(NULL) + seconds);
+ }
+
+ OnLoginSuccess();
+}
diff --git a/protocols/SkypeWeb/src/skype_options.cpp b/protocols/SkypeWeb/src/skype_options.cpp index baaff8b7ab..07f15c215a 100644 --- a/protocols/SkypeWeb/src/skype_options.cpp +++ b/protocols/SkypeWeb/src/skype_options.cpp @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/skype_polling.cpp b/protocols/SkypeWeb/src/skype_polling.cpp index b868e18bcd..0000de3b20 100644 --- a/protocols/SkypeWeb/src/skype_polling.cpp +++ b/protocols/SkypeWeb/src/skype_polling.cpp @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/skype_profile.cpp b/protocols/SkypeWeb/src/skype_profile.cpp index 5612dc9619..f8fbaa2fbe 100644 --- a/protocols/SkypeWeb/src/skype_profile.cpp +++ b/protocols/SkypeWeb/src/skype_profile.cpp @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/skype_proto.cpp b/protocols/SkypeWeb/src/skype_proto.cpp index d99fe64b61..5eb23d11ca 100644 --- a/protocols/SkypeWeb/src/skype_proto.cpp +++ b/protocols/SkypeWeb/src/skype_proto.cpp @@ -1,343 +1,343 @@ -/* -Copyright (c) 2015-22 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" - -CSkypeProto::CSkypeProto(const char* protoName, const wchar_t* userName) : - PROTO<CSkypeProto>(protoName, userName), - m_PopupClasses(1), - m_OutMessages(3, PtrKeySortT), - m_bThreadsTerminated(false), - m_impl(*this), - m_requests(1), - bAutoHistorySync(this, "AutoSync", true), - bMarkAllAsUnread(this, "MarkMesUnread", true), - bUseHostnameAsPlace(this, "UseHostName", true), - bUseBBCodes(this, "UseBBCodes", true), - bUseServerTime(this, "UseServerTime", false), - wstrCListGroup(this, SKYPE_SETTINGS_GROUP, L"Skype"), - wstrPlace(this, "Place", L"") -{ - NETLIBUSER nlu = {}; - nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_HTTPCONNS | NUF_UNICODE; - nlu.szDescriptiveName.w = m_tszUserName; - nlu.szSettingsModule = m_szModuleName; - m_hNetlibUser = Netlib_RegisterUser(&nlu); - - CreateProtoService(PS_CREATEACCMGRUI, &CSkypeProto::OnAccountManagerInit); - CreateProtoService(PS_GETAVATARINFO, &CSkypeProto::SvcGetAvatarInfo); - CreateProtoService(PS_GETAVATARCAPS, &CSkypeProto::SvcGetAvatarCaps); - CreateProtoService(PS_GETMYAVATAR, &CSkypeProto::SvcGetMyAvatar); - CreateProtoService(PS_SETMYAVATAR, &CSkypeProto::SvcSetMyAvatar); - - CreateProtoService(PS_MENU_REQAUTH, &CSkypeProto::OnRequestAuth); - CreateProtoService(PS_MENU_GRANTAUTH, &CSkypeProto::OnGrantAuth); - CreateProtoService(PS_MENU_LOADHISTORY, &CSkypeProto::GetContactHistory); - - HookProtoEvent(ME_OPT_INITIALISE, &CSkypeProto::OnOptionsInit); - HookProtoEvent(ME_DB_EVENT_MARKED_READ, &CSkypeProto::OnDbEventRead); - - m_tszAvatarFolder = std::wstring(VARSW(L"%miranda_avatarcache%")) + L"\\" + m_tszUserName; - CreateDirectoryTreeW(m_tszAvatarFolder.c_str()); - - //sounds - g_plugin.addSound("skype_inc_call", L"SkypeWeb", LPGENW("Incoming call")); - g_plugin.addSound("skype_call_canceled", L"SkypeWeb", LPGENW("Incoming call canceled")); - - m_hPollingThread = ForkThreadEx(&CSkypeProto::PollingThread, NULL, NULL); - - m_szSkypename = getMStringA(SKYPE_SETTINGS_ID); - if (m_szSkypename.IsEmpty()) { - m_szSkypename = getMStringA(SKYPE_SETTINGS_LOGIN); - if (!m_szSkypename.IsEmpty()) { // old settings format, need to update all settings - m_szSkypename.Insert(0, "8:"); - setString(SKYPE_SETTINGS_ID, m_szSkypename); - - for (auto &hContact : AccContacts()) { - CMStringA id(ptrA(getUStringA(hContact, "Skypename"))); - if (!id.IsEmpty()) - setString(hContact, SKYPE_SETTINGS_ID, (isChatRoom(hContact)) ? "19:"+id : "8:"+id); - - ptrW wszNick(getWStringA(hContact, "Nick")); - if (wszNick == nullptr) - setUString(hContact, "Nick", id); - - delSetting(hContact, "Skypename"); - } - } - } - - InitGroupChatModule(); -} - -CSkypeProto::~CSkypeProto() -{ - StopQueue(); - if (m_hRequestQueueThread) { - WaitForSingleObject(m_hRequestQueueThread, INFINITE); - m_hRequestQueueThread = nullptr; - } - - UninitPopups(); - - if (m_hPollingThread) { - WaitForSingleObject(m_hPollingThread, INFINITE); - m_hPollingThread = nullptr; - } -} - -void CSkypeProto::OnModulesLoaded() -{ - setAllContactStatuses(ID_STATUS_OFFLINE, false); - - HookProtoEvent(ME_MSG_PRECREATEEVENT, &CSkypeProto::OnPreCreateMessage); - - InitDBEvents(); - InitPopups(); -} - -void CSkypeProto::OnShutdown() -{ - debugLogA(__FUNCTION__); - - StopQueue(); - - m_bThreadsTerminated = true; - - m_hPollingEvent.Set(); - m_hTrouterEvent.Set(); -} - -INT_PTR CSkypeProto::GetCaps(int type, MCONTACT) -{ - switch (type) { - case PFLAGNUM_1: - return PF1_IM | PF1_AUTHREQ | PF1_CHAT | PF1_BASICSEARCH | PF1_MODEMSG | PF1_FILE; - case PFLAGNUM_2: - return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_HEAVYDND; - case PFLAGNUM_3: - return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_HEAVYDND; - case PFLAGNUM_4: - return PF4_NOAUTHDENYREASON | PF4_SUPPORTTYPING | PF4_AVATARS | PF4_IMSENDOFFLINE | PF4_OFFLINEFILES | PF4_SERVERMSGID; - case PFLAG_UNIQUEIDTEXT: - return (INT_PTR)TranslateT("Skypename"); - } - return 0; -} - -int CSkypeProto::SetAwayMsg(int, const wchar_t *msg) -{ - if (IsOnline()) - PushRequest(new SetStatusMsgRequest(msg ? T2Utf(msg) : "")); - return 0; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -void CSkypeProto::OnReceiveAwayMsg(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest) -{ - JsonReply reply(response); - if (reply.error()) - return; - - MCONTACT hContact = DWORD_PTR(pRequest->pUserInfo); - auto &root = reply.data(); - if (JSONNode &mood = root["mood"]) { - CMStringW str = mood.as_mstring(); - ProtoBroadcastAck(hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)1, (LPARAM)str.c_str()); - } - else { - ProtoBroadcastAck(hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)1, 0); - } -} - -HANDLE CSkypeProto::GetAwayMsg(MCONTACT hContact) -{ - auto *pReq = new GetProfileRequest(this, hContact); - pReq->m_pFunc = &CSkypeProto::OnReceiveAwayMsg; - return (HANDLE)1; -} - -MCONTACT CSkypeProto::AddToList(int, PROTOSEARCHRESULT *psr) -{ - debugLogA(__FUNCTION__); - - if (psr->id.a == nullptr) - return NULL; - - MCONTACT hContact; - if (psr->flags & PSR_UNICODE) - hContact = AddContact(T2Utf(psr->id.w), T2Utf(psr->nick.w)); - else - hContact = AddContact(psr->id.a, psr->nick.a); - - return hContact; -} - -MCONTACT CSkypeProto::AddToListByEvent(int, int, MEVENT hDbEvent) -{ - debugLogA(__FUNCTION__); - - DB::EventInfo dbei; - dbei.cbBlob = -1; - if (db_event_get(hDbEvent, &dbei)) - return NULL; - if (mir_strcmp(dbei.szModule, m_szModuleName)) - return NULL; - if (dbei.eventType != EVENTTYPE_AUTHREQUEST) - return NULL; - - DB::AUTH_BLOB blob(dbei.pBlob); - return AddContact(blob.get_email(), blob.get_nick()); -} - -int CSkypeProto::Authorize(MEVENT hDbEvent) -{ - MCONTACT hContact = GetContactFromAuthEvent(hDbEvent); - if (hContact == INVALID_CONTACT_ID) - return 1; - - PushRequest(new AuthAcceptRequest(getId(hContact))); - return 0; -} - -int CSkypeProto::AuthDeny(MEVENT hDbEvent, const wchar_t*) -{ - MCONTACT hContact = GetContactFromAuthEvent(hDbEvent); - if (hContact == INVALID_CONTACT_ID) - return 1; - - PushRequest(new AuthDeclineRequest(getId(hContact))); - return 0; -} - -int CSkypeProto::AuthRecv(MCONTACT, PROTORECVEVENT* pre) -{ - return Proto_AuthRecv(m_szModuleName, pre); -} - -int CSkypeProto::AuthRequest(MCONTACT hContact, const wchar_t *szMessage) -{ - if (hContact == INVALID_CONTACT_ID) - return 1; - - PushRequest(new AddContactRequest(getId(hContact), T2Utf(szMessage))); - return 0; -} - -int CSkypeProto::GetInfo(MCONTACT hContact, int) -{ - if (isChatRoom(hContact)) - return 1; - - PushRequest(new GetProfileRequest(this, hContact)); - return 0; -} - -int CSkypeProto::SendMsg(MCONTACT hContact, int flags, const char *msg) -{ - return OnSendMessage(hContact, flags, msg); -} - -int CSkypeProto::SetStatus(int iNewStatus) -{ - if (iNewStatus == m_iDesiredStatus) - return 0; - - switch (iNewStatus) { - case ID_STATUS_FREECHAT: iNewStatus = ID_STATUS_ONLINE; break; - case ID_STATUS_NA: iNewStatus = ID_STATUS_AWAY; break; - case ID_STATUS_OCCUPIED: iNewStatus = ID_STATUS_DND; break; - } - - debugLogA(__FUNCTION__ ": changing status from %i to %i", m_iStatus, iNewStatus); - - int old_status = m_iStatus; - m_iDesiredStatus = iNewStatus; - - if (iNewStatus == ID_STATUS_OFFLINE) { - if (m_iStatus > ID_STATUS_CONNECTING + 1 && m_szId) - PushRequest(new DeleteEndpointRequest(this)); - - m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; - // logout - StopQueue(); - - ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, ID_STATUS_OFFLINE); - - m_impl.m_heartBeat.StopSafe(); - - if (!Miranda_IsTerminated()) - setAllContactStatuses(ID_STATUS_OFFLINE, false); - return 0; - } - else { - if (old_status == ID_STATUS_CONNECTING) - return 0; - - if (old_status == ID_STATUS_OFFLINE && m_iStatus == ID_STATUS_OFFLINE) - Login(); - else - PushRequest(new SetStatusRequest(MirandaToSkypeStatus(m_iDesiredStatus))); - } - - ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); - return 0; -} - -int CSkypeProto::UserIsTyping(MCONTACT hContact, int type) -{ - PushRequest(new SendTypingRequest(getId(hContact), type)); - return 0; -} - -int CSkypeProto::RecvContacts(MCONTACT hContact, PROTORECVEVENT* pre) -{ - PROTOSEARCHRESULT **isrList = (PROTOSEARCHRESULT**)pre->szMessage; - - int nCount = *((LPARAM*)pre->lParam); - char* szMessageId = ((char*)pre->lParam + sizeof(LPARAM)); - - //if (GetMessageFromDb(hContact, szMessageId, pre->timestamp)) return 0; - - uint32_t cbBlob = 0; - for (int i = 0; i < nCount; i++) - cbBlob += int(/*mir_wstrlen(isrList[i]->nick.w)*/0 + 2 + mir_wstrlen(isrList[i]->id.w) + mir_strlen(szMessageId)); - - uint8_t *pBlob = (uint8_t*)mir_calloc(cbBlob); - uint8_t *pCurBlob = pBlob; - - for (int i = 0; i < nCount; i++) { - //mir_strcpy((char*)pCurBlob, _T2A(isrList[i]->nick.w)); - pCurBlob += mir_strlen((PCHAR)pCurBlob) + 1; - - mir_strcpy((char*)pCurBlob, _T2A(isrList[i]->id.w)); - pCurBlob += mir_strlen((char*)pCurBlob) + 1; - } - - DBEVENTINFO dbei = {}; - dbei.szModule = m_szModuleName; - dbei.timestamp = pre->timestamp; - dbei.eventType = EVENTTYPE_CONTACTS; - dbei.cbBlob = cbBlob; - dbei.pBlob = pBlob; - dbei.flags = (pre->flags & PREF_CREATEREAD) ? DBEF_READ : 0; - db_event_add(hContact, &dbei); - - mir_free(pBlob); - return 0; -} +/*
+Copyright (c) 2015-23 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"
+
+CSkypeProto::CSkypeProto(const char* protoName, const wchar_t* userName) :
+ PROTO<CSkypeProto>(protoName, userName),
+ m_PopupClasses(1),
+ m_OutMessages(3, PtrKeySortT),
+ m_bThreadsTerminated(false),
+ m_impl(*this),
+ m_requests(1),
+ bAutoHistorySync(this, "AutoSync", true),
+ bMarkAllAsUnread(this, "MarkMesUnread", true),
+ bUseHostnameAsPlace(this, "UseHostName", true),
+ bUseBBCodes(this, "UseBBCodes", true),
+ bUseServerTime(this, "UseServerTime", false),
+ wstrCListGroup(this, SKYPE_SETTINGS_GROUP, L"Skype"),
+ wstrPlace(this, "Place", L"")
+{
+ NETLIBUSER nlu = {};
+ nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_HTTPCONNS | NUF_UNICODE;
+ nlu.szDescriptiveName.w = m_tszUserName;
+ nlu.szSettingsModule = m_szModuleName;
+ m_hNetlibUser = Netlib_RegisterUser(&nlu);
+
+ CreateProtoService(PS_CREATEACCMGRUI, &CSkypeProto::OnAccountManagerInit);
+ CreateProtoService(PS_GETAVATARINFO, &CSkypeProto::SvcGetAvatarInfo);
+ CreateProtoService(PS_GETAVATARCAPS, &CSkypeProto::SvcGetAvatarCaps);
+ CreateProtoService(PS_GETMYAVATAR, &CSkypeProto::SvcGetMyAvatar);
+ CreateProtoService(PS_SETMYAVATAR, &CSkypeProto::SvcSetMyAvatar);
+
+ CreateProtoService(PS_MENU_REQAUTH, &CSkypeProto::OnRequestAuth);
+ CreateProtoService(PS_MENU_GRANTAUTH, &CSkypeProto::OnGrantAuth);
+ CreateProtoService(PS_MENU_LOADHISTORY, &CSkypeProto::GetContactHistory);
+
+ HookProtoEvent(ME_OPT_INITIALISE, &CSkypeProto::OnOptionsInit);
+ HookProtoEvent(ME_DB_EVENT_MARKED_READ, &CSkypeProto::OnDbEventRead);
+
+ m_tszAvatarFolder = std::wstring(VARSW(L"%miranda_avatarcache%")) + L"\\" + m_tszUserName;
+ CreateDirectoryTreeW(m_tszAvatarFolder.c_str());
+
+ //sounds
+ g_plugin.addSound("skype_inc_call", L"SkypeWeb", LPGENW("Incoming call"));
+ g_plugin.addSound("skype_call_canceled", L"SkypeWeb", LPGENW("Incoming call canceled"));
+
+ m_hPollingThread = ForkThreadEx(&CSkypeProto::PollingThread, NULL, NULL);
+
+ m_szSkypename = getMStringA(SKYPE_SETTINGS_ID);
+ if (m_szSkypename.IsEmpty()) {
+ m_szSkypename = getMStringA(SKYPE_SETTINGS_LOGIN);
+ if (!m_szSkypename.IsEmpty()) { // old settings format, need to update all settings
+ m_szSkypename.Insert(0, "8:");
+ setString(SKYPE_SETTINGS_ID, m_szSkypename);
+
+ for (auto &hContact : AccContacts()) {
+ CMStringA id(ptrA(getUStringA(hContact, "Skypename")));
+ if (!id.IsEmpty())
+ setString(hContact, SKYPE_SETTINGS_ID, (isChatRoom(hContact)) ? "19:"+id : "8:"+id);
+
+ ptrW wszNick(getWStringA(hContact, "Nick"));
+ if (wszNick == nullptr)
+ setUString(hContact, "Nick", id);
+
+ delSetting(hContact, "Skypename");
+ }
+ }
+ }
+
+ InitGroupChatModule();
+}
+
+CSkypeProto::~CSkypeProto()
+{
+ StopQueue();
+ if (m_hRequestQueueThread) {
+ WaitForSingleObject(m_hRequestQueueThread, INFINITE);
+ m_hRequestQueueThread = nullptr;
+ }
+
+ UninitPopups();
+
+ if (m_hPollingThread) {
+ WaitForSingleObject(m_hPollingThread, INFINITE);
+ m_hPollingThread = nullptr;
+ }
+}
+
+void CSkypeProto::OnModulesLoaded()
+{
+ setAllContactStatuses(ID_STATUS_OFFLINE, false);
+
+ HookProtoEvent(ME_MSG_PRECREATEEVENT, &CSkypeProto::OnPreCreateMessage);
+
+ InitDBEvents();
+ InitPopups();
+}
+
+void CSkypeProto::OnShutdown()
+{
+ debugLogA(__FUNCTION__);
+
+ StopQueue();
+
+ m_bThreadsTerminated = true;
+
+ m_hPollingEvent.Set();
+ m_hTrouterEvent.Set();
+}
+
+INT_PTR CSkypeProto::GetCaps(int type, MCONTACT)
+{
+ switch (type) {
+ case PFLAGNUM_1:
+ return PF1_IM | PF1_AUTHREQ | PF1_CHAT | PF1_BASICSEARCH | PF1_MODEMSG | PF1_FILE;
+ case PFLAGNUM_2:
+ return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_HEAVYDND;
+ case PFLAGNUM_3:
+ return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_HEAVYDND;
+ case PFLAGNUM_4:
+ return PF4_NOAUTHDENYREASON | PF4_SUPPORTTYPING | PF4_AVATARS | PF4_IMSENDOFFLINE | PF4_OFFLINEFILES | PF4_SERVERMSGID;
+ case PFLAG_UNIQUEIDTEXT:
+ return (INT_PTR)TranslateT("Skypename");
+ }
+ return 0;
+}
+
+int CSkypeProto::SetAwayMsg(int, const wchar_t *msg)
+{
+ if (IsOnline())
+ PushRequest(new SetStatusMsgRequest(msg ? T2Utf(msg) : ""));
+ return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CSkypeProto::OnReceiveAwayMsg(NETLIBHTTPREQUEST *response, AsyncHttpRequest *pRequest)
+{
+ JsonReply reply(response);
+ if (reply.error())
+ return;
+
+ MCONTACT hContact = DWORD_PTR(pRequest->pUserInfo);
+ auto &root = reply.data();
+ if (JSONNode &mood = root["mood"]) {
+ CMStringW str = mood.as_mstring();
+ ProtoBroadcastAck(hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)1, (LPARAM)str.c_str());
+ }
+ else {
+ ProtoBroadcastAck(hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)1, 0);
+ }
+}
+
+HANDLE CSkypeProto::GetAwayMsg(MCONTACT hContact)
+{
+ auto *pReq = new GetProfileRequest(this, hContact);
+ pReq->m_pFunc = &CSkypeProto::OnReceiveAwayMsg;
+ return (HANDLE)1;
+}
+
+MCONTACT CSkypeProto::AddToList(int, PROTOSEARCHRESULT *psr)
+{
+ debugLogA(__FUNCTION__);
+
+ if (psr->id.a == nullptr)
+ return NULL;
+
+ MCONTACT hContact;
+ if (psr->flags & PSR_UNICODE)
+ hContact = AddContact(T2Utf(psr->id.w), T2Utf(psr->nick.w));
+ else
+ hContact = AddContact(psr->id.a, psr->nick.a);
+
+ return hContact;
+}
+
+MCONTACT CSkypeProto::AddToListByEvent(int, int, MEVENT hDbEvent)
+{
+ debugLogA(__FUNCTION__);
+
+ DB::EventInfo dbei;
+ dbei.cbBlob = -1;
+ if (db_event_get(hDbEvent, &dbei))
+ return NULL;
+ if (mir_strcmp(dbei.szModule, m_szModuleName))
+ return NULL;
+ if (dbei.eventType != EVENTTYPE_AUTHREQUEST)
+ return NULL;
+
+ DB::AUTH_BLOB blob(dbei.pBlob);
+ return AddContact(blob.get_email(), blob.get_nick());
+}
+
+int CSkypeProto::Authorize(MEVENT hDbEvent)
+{
+ MCONTACT hContact = GetContactFromAuthEvent(hDbEvent);
+ if (hContact == INVALID_CONTACT_ID)
+ return 1;
+
+ PushRequest(new AuthAcceptRequest(getId(hContact)));
+ return 0;
+}
+
+int CSkypeProto::AuthDeny(MEVENT hDbEvent, const wchar_t*)
+{
+ MCONTACT hContact = GetContactFromAuthEvent(hDbEvent);
+ if (hContact == INVALID_CONTACT_ID)
+ return 1;
+
+ PushRequest(new AuthDeclineRequest(getId(hContact)));
+ return 0;
+}
+
+int CSkypeProto::AuthRecv(MCONTACT, PROTORECVEVENT* pre)
+{
+ return Proto_AuthRecv(m_szModuleName, pre);
+}
+
+int CSkypeProto::AuthRequest(MCONTACT hContact, const wchar_t *szMessage)
+{
+ if (hContact == INVALID_CONTACT_ID)
+ return 1;
+
+ PushRequest(new AddContactRequest(getId(hContact), T2Utf(szMessage)));
+ return 0;
+}
+
+int CSkypeProto::GetInfo(MCONTACT hContact, int)
+{
+ if (isChatRoom(hContact))
+ return 1;
+
+ PushRequest(new GetProfileRequest(this, hContact));
+ return 0;
+}
+
+int CSkypeProto::SendMsg(MCONTACT hContact, int flags, const char *msg)
+{
+ return OnSendMessage(hContact, flags, msg);
+}
+
+int CSkypeProto::SetStatus(int iNewStatus)
+{
+ if (iNewStatus == m_iDesiredStatus)
+ return 0;
+
+ switch (iNewStatus) {
+ case ID_STATUS_FREECHAT: iNewStatus = ID_STATUS_ONLINE; break;
+ case ID_STATUS_NA: iNewStatus = ID_STATUS_AWAY; break;
+ case ID_STATUS_OCCUPIED: iNewStatus = ID_STATUS_DND; break;
+ }
+
+ debugLogA(__FUNCTION__ ": changing status from %i to %i", m_iStatus, iNewStatus);
+
+ int old_status = m_iStatus;
+ m_iDesiredStatus = iNewStatus;
+
+ if (iNewStatus == ID_STATUS_OFFLINE) {
+ if (m_iStatus > ID_STATUS_CONNECTING + 1 && m_szId)
+ PushRequest(new DeleteEndpointRequest(this));
+
+ m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
+ // logout
+ StopQueue();
+
+ ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, ID_STATUS_OFFLINE);
+
+ m_impl.m_heartBeat.StopSafe();
+
+ if (!Miranda_IsTerminated())
+ setAllContactStatuses(ID_STATUS_OFFLINE, false);
+ return 0;
+ }
+ else {
+ if (old_status == ID_STATUS_CONNECTING)
+ return 0;
+
+ if (old_status == ID_STATUS_OFFLINE && m_iStatus == ID_STATUS_OFFLINE)
+ Login();
+ else
+ PushRequest(new SetStatusRequest(MirandaToSkypeStatus(m_iDesiredStatus)));
+ }
+
+ ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus);
+ return 0;
+}
+
+int CSkypeProto::UserIsTyping(MCONTACT hContact, int type)
+{
+ PushRequest(new SendTypingRequest(getId(hContact), type));
+ return 0;
+}
+
+int CSkypeProto::RecvContacts(MCONTACT hContact, PROTORECVEVENT* pre)
+{
+ PROTOSEARCHRESULT **isrList = (PROTOSEARCHRESULT**)pre->szMessage;
+
+ int nCount = *((LPARAM*)pre->lParam);
+ char* szMessageId = ((char*)pre->lParam + sizeof(LPARAM));
+
+ //if (GetMessageFromDb(hContact, szMessageId, pre->timestamp)) return 0;
+
+ uint32_t cbBlob = 0;
+ for (int i = 0; i < nCount; i++)
+ cbBlob += int(/*mir_wstrlen(isrList[i]->nick.w)*/0 + 2 + mir_wstrlen(isrList[i]->id.w) + mir_strlen(szMessageId));
+
+ uint8_t *pBlob = (uint8_t*)mir_calloc(cbBlob);
+ uint8_t *pCurBlob = pBlob;
+
+ for (int i = 0; i < nCount; i++) {
+ //mir_strcpy((char*)pCurBlob, _T2A(isrList[i]->nick.w));
+ pCurBlob += mir_strlen((PCHAR)pCurBlob) + 1;
+
+ mir_strcpy((char*)pCurBlob, _T2A(isrList[i]->id.w));
+ pCurBlob += mir_strlen((char*)pCurBlob) + 1;
+ }
+
+ DBEVENTINFO dbei = {};
+ dbei.szModule = m_szModuleName;
+ dbei.timestamp = pre->timestamp;
+ dbei.eventType = EVENTTYPE_CONTACTS;
+ dbei.cbBlob = cbBlob;
+ dbei.pBlob = pBlob;
+ dbei.flags = (pre->flags & PREF_CREATEREAD) ? DBEF_READ : 0;
+ db_event_add(hContact, &dbei);
+
+ mir_free(pBlob);
+ return 0;
+}
diff --git a/protocols/SkypeWeb/src/skype_proto.h b/protocols/SkypeWeb/src/skype_proto.h index 4630cde68f..3517ae742a 100644 --- a/protocols/SkypeWeb/src/skype_proto.h +++ b/protocols/SkypeWeb/src/skype_proto.h @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/skype_search.cpp b/protocols/SkypeWeb/src/skype_search.cpp index e47eba7243..51a4952021 100644 --- a/protocols/SkypeWeb/src/skype_search.cpp +++ b/protocols/SkypeWeb/src/skype_search.cpp @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/skype_trouter.cpp b/protocols/SkypeWeb/src/skype_trouter.cpp index bb8a74385b..65e38d4d41 100644 --- a/protocols/SkypeWeb/src/skype_trouter.cpp +++ b/protocols/SkypeWeb/src/skype_trouter.cpp @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/skype_utils.cpp b/protocols/SkypeWeb/src/skype_utils.cpp index 903309054b..fc7a4bb6b1 100644 --- a/protocols/SkypeWeb/src/skype_utils.cpp +++ b/protocols/SkypeWeb/src/skype_utils.cpp @@ -1,679 +1,679 @@ -/* -Copyright (c) 2015-22 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" - -#pragma warning(disable:4566) - -time_t CSkypeProto::IsoToUnixTime(const std::string &stamp) -{ - char date[9]; - int i, y; - - if (stamp.empty()) - return 0; - - char *p = NEWSTR_ALLOCA(stamp.c_str()); - - // skip '-' chars - int si = 0, sj = 0; - while (true) { - if (p[si] == '-') - si++; - else if (!(p[sj++] = p[si++])) - break; - } - - // Get the date part - for (i = 0; *p != '\0' && i < 8 && isdigit(*p); p++, i++) - date[i] = *p; - - // Parse year - if (i == 6) { - // 2-digit year (1970-2069) - y = (date[0] - '0') * 10 + (date[1] - '0'); - if (y < 70) y += 100; - } - else if (i == 8) { - // 4-digit year - y = (date[0] - '0') * 1000 + (date[1] - '0') * 100 + (date[2] - '0') * 10 + date[3] - '0'; - y -= 1900; - } - else return 0; - - struct tm timestamp; - timestamp.tm_year = y; - - // Parse month - timestamp.tm_mon = (date[i - 4] - '0') * 10 + date[i - 3] - '0' - 1; - - // Parse date - timestamp.tm_mday = (date[i - 2] - '0') * 10 + date[i - 1] - '0'; - - // Skip any date/time delimiter - for (; *p != '\0' && !isdigit(*p); p++); - - // Parse time - if (sscanf(p, "%d:%d:%d", ×tamp.tm_hour, ×tamp.tm_min, ×tamp.tm_sec) != 3) - return (time_t)0; - - timestamp.tm_isdst = 0; // DST is already present in _timezone below - time_t t = mktime(×tamp); - - _tzset(); - t -= _timezone; - return (t >= 0) ? t : 0; -} - -struct HtmlEntity -{ - const char *entity; - const char *symbol; -}; - -const HtmlEntity htmlEntities[] = -{ - { "AElig", "\u00C6" }, - { "Aacute", "\u00C1" }, - { "Acirc", "\u00C2" }, - { "Agrave", "\u00C0" }, - { "Alpha", "\u0391" }, - { "Aring", "\u00C5" }, - { "Atilde", "\u00C3" }, - { "Auml", "\u00C4" }, - { "Beta", "\u0392" }, - { "Ccedil", "\u00C7" }, - { "Chi", "\u03A7" }, - { "Dagger", "‡" }, - { "Delta", "\u0394" }, - { "ETH", "\u00D0" }, - { "Eacute", "\u00C9" }, - { "Ecirc", "\u00CA" }, - { "Egrave", "\u00C8" }, - { "Epsilon", "\u0395" }, - { "Eta", "\u0397" }, - { "Euml", "\u00CB" }, - { "Gamma", "\u0393" }, - { "Iacute", "\u00CD" }, - { "Icirc", "\u00CE" }, - { "Igrave", "\u00CC" }, - { "Iota", "\u0399" }, - { "Iuml", "\u00CF" }, - { "Kappa", "\u039A" }, - { "Lambda", "\u039B" }, - { "Mu", "\u039C" }, - { "Ntilde", "\u00D1" }, - { "Nu", "\u039D" }, - { "OElig", "\u0152" }, - { "Oacute", "\u00D3" }, - { "Ocirc", "\u00D4" }, - { "Ograve", "\u00D2" }, - { "Omega", "\u03A9" }, - { "Omicron", "\u039F" }, - { "Oslash", "\u00D8" }, - { "Otilde", "\u00D5" }, - { "Ouml", "\u00D6" }, - { "Phi", "\u03A6" }, - { "Pi", "\u03A0" }, - { "Prime", "\u2033" }, - { "Psi", "\u03A8" }, - { "Rho", "\u03A1" }, - { "Scaron", "Š" }, - { "Sigma", "Σ" }, - { "THORN", "Þ" }, - { "Tau", "Τ" }, - { "Theta", "Θ" }, - { "Uacute", "Ú" }, - { "Ucirc", "Û" }, - { "Ugrave", "Ù" }, - { "Upsilon", "Υ" }, - { "Uuml", "Ü" }, - { "Xi", "Ξ" }, - { "Yacute", "Ý" }, - { "Yuml", "Ÿ" }, - { "Zeta", "Ζ" }, - { "aacute", "á" }, - { "acirc", "â" }, - { "acute", "´" }, - { "aelig", "æ" }, - { "agrave", "à" }, - { "alefsym", "ℵ" }, - { "alpha", "α" }, - { "amp", "&" }, - { "and", "∧" }, - { "ang", "∠" }, - { "apos", "'" }, - { "aring", "å" }, - { "asymp", "≈" }, - { "atilde", "ã" }, - { "auml", "ä" }, - { "bdquo", "„" }, - { "beta", "β" }, - { "brvbar", "¦" }, - { "bull", "•" }, - { "cap", "∩" }, - { "ccedil", "ç" }, - { "cedil", "¸" }, - { "cent", "¢" }, - { "chi", "χ" }, - { "circ", "ˆ" }, - { "clubs", "♣" }, - { "cong", "≅" }, - { "copy", "©" }, - { "crarr", "↵" }, - { "cup", "∪" }, - { "curren", "¤" }, - { "dArr", "⇓" }, - { "dagger", "†" }, - { "darr", "↓" }, - { "deg", "°" }, - { "delta", "δ" }, - { "diams", "♦" }, - { "divide", "÷" }, - { "eacute", "é" }, - { "ecirc", "ê" }, - { "egrave", "è" }, - { "empty", "∅" }, - { "emsp", " " }, - { "ensp", " " }, - { "epsilon", "ε" }, - { "equiv", "≡" }, - { "eta", "η" }, - { "eth", "ð" }, - { "euml", "ë" }, - { "euro", "€" }, - { "exist", "∃" }, - { "fnof", "ƒ" }, - { "forall", "∀" }, - { "frac12", "½" }, - { "frac14", "¼" }, - { "frac34", "¾" }, - { "frasl", "⁄" }, - { "gamma", "γ" }, - { "ge", "≥" }, - { "gt", ">" }, - { "hArr", "⇔" }, - { "harr", "↔" }, - { "hearts", "♥" }, - { "hellip", "…" }, - { "iacute", "í" }, - { "icirc", "î" }, - { "iexcl", "¡" }, - { "igrave", "ì" }, - { "image", "ℑ" }, - { "infin", "∞" }, - { "int", "∫" }, - { "iota", "ι" }, - { "iquest", "¿" }, - { "isin", "∈" }, - { "iuml", "ï" }, - { "kappa", "κ" }, - { "lArr", "⇐" }, - { "lambda", "λ" }, - { "lang", "〈" }, - { "laquo", "«" }, - { "larr", "←" }, - { "lceil", "⌈" }, - { "ldquo", "“" }, - { "le", "≤" }, - { "lfloor", "⌊" }, - { "lowast", "∗" }, - { "loz", "◊" }, - { "lrm", "\xE2\x80\x8E" }, - { "lsaquo", "‹" }, - { "lsquo", "‘" }, - { "lt", "<" }, - { "macr", "¯" }, - { "mdash", "—" }, - { "micro", "µ" }, - { "middot", "·" }, - { "minus", "−" }, - { "mu", "μ" }, - { "nabla", "∇" }, - { "nbsp", " " }, - { "ndash", "–" }, - { "ne", "≠" }, - { "ni", "∋" }, - { "not", "¬" }, - { "notin", "∉" }, - { "nsub", "⊄" }, - { "ntilde", "ñ" }, - { "nu", "ν" }, - { "oacute", "ó" }, - { "ocirc", "ô" }, - { "oelig", "œ" }, - { "ograve", "ò" }, - { "oline", "‾" }, - { "omega", "ω" }, - { "omicron", "ο" }, - { "oplus", "⊕" }, - { "or", "∨" }, - { "ordf", "ª" }, - { "ordm", "º" }, - { "oslash", "ø" }, - { "otilde", "õ" }, - { "otimes", "⊗" }, - { "ouml", "ö" }, - { "para", "¶" }, - { "part", "∂" }, - { "permil", "‰" }, - { "perp", "⊥" }, - { "phi", "φ" }, - { "pi", "π" }, - { "piv", "ϖ" }, - { "plusmn", "±" }, - { "pound", "£" }, - { "prime", "′" }, - { "prod", "∏" }, - { "prop", "∝" }, - { "psi", "ψ" }, - { "quot", "\"" }, - { "rArr", "⇒" }, - { "radic", "√" }, - { "rang", "〉" }, - { "raquo", "»" }, - { "rarr", "→" }, - { "rceil", "⌉" }, - { "rdquo", "”" }, - { "real", "ℜ" }, - { "reg", "®" }, - { "rfloor", "⌋" }, - { "rho", "ρ" }, - { "rlm", "\xE2\x80\x8F" }, - { "rsaquo", "›" }, - { "rsquo", "’" }, - { "sbquo", "‚" }, - { "scaron", "š" }, - { "sdot", "⋅" }, - { "sect", "§" }, - { "shy", "\xC2\xAD" }, - { "sigma", "σ" }, - { "sigmaf", "ς" }, - { "sim", "∼" }, - { "spades", "♠" }, - { "sub", "⊂" }, - { "sube", "⊆" }, - { "sum", "∑" }, - { "sup", "⊃" }, - { "sup1", "¹" }, - { "sup2", "²" }, - { "sup3", "³" }, - { "supe", "⊇" }, - { "szlig", "ß" }, - { "tau", "τ" }, - { "there4", "∴" }, - { "theta", "θ" }, - { "thetasym", "ϑ" }, - { "thinsp", " " }, - { "thorn", "þ" }, - { "tilde", "˜" }, - { "times", "×" }, - { "trade", "™" }, - { "uArr", "⇑" }, - { "uacute", "ú" }, - { "uarr", "↑" }, - { "ucirc", "û" }, - { "ugrave", "ù" }, - { "uml", "¨" }, - { "upsih", "ϒ" }, - { "upsilon", "υ" }, - { "uuml", "ü" }, - { "weierp", "℘" }, - { "xi", "ξ" }, - { "yacute", "ý" }, - { "yen", "¥" }, - { "yuml", "ÿ" }, - { "zeta", "ζ" }, - { "zwj", "\xE2\x80\x8D" }, - { "zwnj", "\xE2\x80\x8C" } -}; - -CMStringW RemoveHtml(const CMStringW &data) -{ - CMStringW new_string; - - for (int i = 0; i < data.GetLength(); i++) { - wchar_t c = data[i]; - if (c == '<') { - i = data.Find('>', i); - if (i == -1) - break; - - continue; - } - - // special character - if (c == '&') { - int begin = i; - i = data.Find(';', i); - if (i == -1) - i = begin; - else { - CMStringW entity = data.Mid(begin + 1, i - begin - 1); - - bool found = false; - if (entity.GetLength() > 1 && entity[0] == '#') { - // Numeric replacement - bool hex = false; - if (entity[1] == 'x') { - hex = true; - entity.Delete(0, 2); - } - else entity.Delete(0, 1); - - if (!entity.IsEmpty()) { - found = true; - errno = 0; - unsigned long value = wcstoul(entity, nullptr, hex ? 16 : 10); - if (errno != 0) { // error with conversion in strtoul, ignore the result - found = false; - } - else if (value <= 127) { // U+0000 .. U+007F - new_string += (char)value; - } - else if (value >= 128 && value <= 2047) { // U+0080 .. U+07FF - new_string += (char)(192 + (value / 64)); - new_string += (char)(128 + (value % 64)); - } - else if (value >= 2048 && value <= 65535) { // U+0800 .. U+FFFF - new_string += (char)(224 + (value / 4096)); - new_string += (char)(128 + ((value / 64) % 64)); - new_string += (char)(128 + (value % 64)); - } - else { - new_string += (char)((value >> 24) & 0xFF); - new_string += (char)((value >> 16) & 0xFF); - new_string += (char)((value >> 8) & 0xFF); - new_string += (char)((value) & 0xFF); - } - } - } - else { - // Keyword replacement - CMStringA tmp = entity; - for (auto &it : htmlEntities) { - if (!mir_strcmpi(tmp, it.entity)) { - new_string += it.symbol; - found = true; - break; - } - } - } - - if (found) - continue; - else - i = begin; - } - } - - new_string.AppendChar(c); - } - - return new_string; -} - -const char* CSkypeProto::MirandaToSkypeStatus(int status) -{ - switch (status) { - case ID_STATUS_AWAY: - return "Away"; - - case ID_STATUS_DND: - return "Busy"; - - case ID_STATUS_IDLE: - return "Idle"; - - case ID_STATUS_INVISIBLE: - return "Hidden"; - } - return "Online"; -} - -int CSkypeProto::SkypeToMirandaStatus(const char *status) -{ - if (!mir_strcmpi(status, "Online")) - return ID_STATUS_ONLINE; - else if (!mir_strcmpi(status, "Hidden")) - return ID_STATUS_INVISIBLE; - else if (!mir_strcmpi(status, "Away")) - return ID_STATUS_AWAY; - else if (!mir_strcmpi(status, "Idle")) - return ID_STATUS_AWAY; - else if (!mir_strcmpi(status, "Busy")) - return ID_STATUS_DND; - else - return ID_STATUS_OFFLINE; -} - -bool CSkypeProto::IsFileExists(std::wstring path) -{ - return _waccess(path.c_str(), 0) == 0; -} - -const char* GetSkypeNick(const char *szSkypeId) -{ - if (auto *p = strchr(szSkypeId, ':')) - return p + 1; - return szSkypeId; -} - -const wchar_t* GetSkypeNick(const wchar_t *szSkypeId) -{ - if (auto *p = wcsrchr(szSkypeId, ':')) - return p + 1; - return szSkypeId; -} - -///////////////////////////////////////////////////////////////////////////////////////// -// url parsing - -CMStringA ParseUrl(const char *url, const char *token) -{ - if (url == nullptr) - return CMStringA(); - - auto *start = strstr(url, token); - if (start == nullptr) - return CMStringA(); - - auto *end = strchr(++start, '/'); - if (end == nullptr) - return CMStringA(start); - return CMStringA(start, end - start); -} - -CMStringW ParseUrl(const wchar_t *url, const wchar_t *token) -{ - if (url == nullptr) - return CMStringW(); - - auto *start = wcsstr(url, token); - if (start == nullptr) - return CMStringW(); - - auto *end = wcschr(++start, '/'); - if (end == nullptr) - return CMStringW(start); - return CMStringW(start, end - start); -} - -///////////////////////////////////////////////////////////////////////////////////////// - -static int possibleTypes[] = { 1, 2, 8, 19 }; - -CMStringA UrlToSkypeId(const char *url, int *pUserType) -{ - int userType = -1; - CMStringA szResult; - - if (url != nullptr) { - for (auto &it : possibleTypes) { - char tmp[10]; - sprintf_s(tmp, "/%d:", it); - if (strstr(url, tmp)) { - userType = it; - szResult = ParseUrl(url, tmp); - break; - } - } - } - - if (pUserType) - *pUserType = userType; - - return szResult; -} - -CMStringW UrlToSkypeId(const wchar_t *url, int *pUserType) -{ - int userType = -1; - CMStringW szResult; - - if (url != nullptr) { - for (auto &it : possibleTypes) { - wchar_t tmp[10]; - swprintf_s(tmp, L"/%d:", it); - if (wcsstr(url, tmp)) { - userType = it; - szResult = ParseUrl(url, tmp); - break; - } - } - } - - if (pUserType) - *pUserType = userType; - - return szResult; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -INT_PTR CSkypeProto::ParseSkypeUriService(WPARAM, LPARAM lParam) -{ - wchar_t *arg = (wchar_t *)lParam; - if (arg == nullptr) - return 1; - - // skip leading prefix - wchar_t szUri[1024]; - wcsncpy_s(szUri, arg, _TRUNCATE); - wchar_t *szJid = wcschr(szUri, ':'); - if (szJid == nullptr) - return 1; - - // empty jid? - if (!*szJid) - return 1; - - // command code - wchar_t *szCommand = szJid; - szCommand = wcschr(szCommand, '?'); - if (szCommand) - *(szCommand++) = 0; - - // parameters - wchar_t *szSecondParam = szCommand ? wcschr(szCommand, '&') : nullptr; - if (szSecondParam) - *(szSecondParam++) = 0; - - // no command or message command - if (!szCommand || !mir_wstrcmpi(szCommand, L"chat")) { - if (szSecondParam) { - wchar_t *szChatId = wcsstr(szSecondParam, L"id="); - if (szChatId) { - szChatId += 5; - StartChatRoom(szChatId, szChatId); - return 0; - } - } - MCONTACT hContact = AddContact(_T2A(szJid), nullptr, true); - CallService(MS_MSG_SENDMESSAGE, (WPARAM)hContact, NULL); - return 0; - } - - if (!mir_wstrcmpi(szCommand, L"call")) { - MCONTACT hContact = AddContact(_T2A(szJid), nullptr, true); - NotifyEventHooks(g_hCallEvent, (WPARAM)hContact, (LPARAM)0); - return 0; - } - - if (!mir_wstrcmpi(szCommand, L"userinfo")) - return 0; - - if (!mir_wstrcmpi(szCommand, L"add")) { - MCONTACT hContact = FindContact(_T2A(szJid)); - if (hContact == NULL) { - PROTOSEARCHRESULT psr = { 0 }; - psr.cbSize = sizeof(psr); - psr.id.w = mir_wstrdup(szJid); - psr.nick.w = mir_wstrdup(szJid); - psr.flags = PSR_UNICODE; - Contact::AddBySearch(m_szModuleName, &psr); - } - return 0; - } - - if (!mir_wstrcmpi(szCommand, L"sendfile")) { - MCONTACT hContact = AddContact(_T2A(szJid), nullptr, true); - CallService(MS_FILE_SENDFILE, hContact, NULL); - return 1; - } - - if (!mir_wstrcmpi(szCommand, L"voicemail")) - return 1; - - return 1; -} - -INT_PTR CSkypeProto::GlobalParseSkypeUriService(WPARAM wParam, LPARAM lParam) -{ - for (auto &it : CMPlugin::g_arInstances) - if (it->IsOnline()) - return it->ParseSkypeUriService(wParam, lParam); - - return 1; -} - -///////////////////////////////////////////////////////////////////////////////////////// - -JsonReply::JsonReply(NETLIBHTTPREQUEST *pReply) -{ - if (pReply == nullptr) { - m_errorCode = 500; - return; - } - - m_errorCode = pReply->resultCode; - if (m_errorCode != 200) - return; - - m_root = json_parse(pReply->pData); - if (m_root == nullptr) { - m_errorCode = 500; - return; - } - - m_errorCode = (*m_root)["status"]["code"].as_int(); -} - -JsonReply::~JsonReply() -{ - json_delete(m_root); -} +/*
+Copyright (c) 2015-23 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"
+
+#pragma warning(disable:4566)
+
+time_t CSkypeProto::IsoToUnixTime(const std::string &stamp)
+{
+ char date[9];
+ int i, y;
+
+ if (stamp.empty())
+ return 0;
+
+ char *p = NEWSTR_ALLOCA(stamp.c_str());
+
+ // skip '-' chars
+ int si = 0, sj = 0;
+ while (true) {
+ if (p[si] == '-')
+ si++;
+ else if (!(p[sj++] = p[si++]))
+ break;
+ }
+
+ // Get the date part
+ for (i = 0; *p != '\0' && i < 8 && isdigit(*p); p++, i++)
+ date[i] = *p;
+
+ // Parse year
+ if (i == 6) {
+ // 2-digit year (1970-2069)
+ y = (date[0] - '0') * 10 + (date[1] - '0');
+ if (y < 70) y += 100;
+ }
+ else if (i == 8) {
+ // 4-digit year
+ y = (date[0] - '0') * 1000 + (date[1] - '0') * 100 + (date[2] - '0') * 10 + date[3] - '0';
+ y -= 1900;
+ }
+ else return 0;
+
+ struct tm timestamp;
+ timestamp.tm_year = y;
+
+ // Parse month
+ timestamp.tm_mon = (date[i - 4] - '0') * 10 + date[i - 3] - '0' - 1;
+
+ // Parse date
+ timestamp.tm_mday = (date[i - 2] - '0') * 10 + date[i - 1] - '0';
+
+ // Skip any date/time delimiter
+ for (; *p != '\0' && !isdigit(*p); p++);
+
+ // Parse time
+ if (sscanf(p, "%d:%d:%d", ×tamp.tm_hour, ×tamp.tm_min, ×tamp.tm_sec) != 3)
+ return (time_t)0;
+
+ timestamp.tm_isdst = 0; // DST is already present in _timezone below
+ time_t t = mktime(×tamp);
+
+ _tzset();
+ t -= _timezone;
+ return (t >= 0) ? t : 0;
+}
+
+struct HtmlEntity
+{
+ const char *entity;
+ const char *symbol;
+};
+
+const HtmlEntity htmlEntities[] =
+{
+ { "AElig", "\u00C6" },
+ { "Aacute", "\u00C1" },
+ { "Acirc", "\u00C2" },
+ { "Agrave", "\u00C0" },
+ { "Alpha", "\u0391" },
+ { "Aring", "\u00C5" },
+ { "Atilde", "\u00C3" },
+ { "Auml", "\u00C4" },
+ { "Beta", "\u0392" },
+ { "Ccedil", "\u00C7" },
+ { "Chi", "\u03A7" },
+ { "Dagger", "‡" },
+ { "Delta", "\u0394" },
+ { "ETH", "\u00D0" },
+ { "Eacute", "\u00C9" },
+ { "Ecirc", "\u00CA" },
+ { "Egrave", "\u00C8" },
+ { "Epsilon", "\u0395" },
+ { "Eta", "\u0397" },
+ { "Euml", "\u00CB" },
+ { "Gamma", "\u0393" },
+ { "Iacute", "\u00CD" },
+ { "Icirc", "\u00CE" },
+ { "Igrave", "\u00CC" },
+ { "Iota", "\u0399" },
+ { "Iuml", "\u00CF" },
+ { "Kappa", "\u039A" },
+ { "Lambda", "\u039B" },
+ { "Mu", "\u039C" },
+ { "Ntilde", "\u00D1" },
+ { "Nu", "\u039D" },
+ { "OElig", "\u0152" },
+ { "Oacute", "\u00D3" },
+ { "Ocirc", "\u00D4" },
+ { "Ograve", "\u00D2" },
+ { "Omega", "\u03A9" },
+ { "Omicron", "\u039F" },
+ { "Oslash", "\u00D8" },
+ { "Otilde", "\u00D5" },
+ { "Ouml", "\u00D6" },
+ { "Phi", "\u03A6" },
+ { "Pi", "\u03A0" },
+ { "Prime", "\u2033" },
+ { "Psi", "\u03A8" },
+ { "Rho", "\u03A1" },
+ { "Scaron", "Š" },
+ { "Sigma", "Σ" },
+ { "THORN", "Þ" },
+ { "Tau", "Τ" },
+ { "Theta", "Θ" },
+ { "Uacute", "Ú" },
+ { "Ucirc", "Û" },
+ { "Ugrave", "Ù" },
+ { "Upsilon", "Υ" },
+ { "Uuml", "Ü" },
+ { "Xi", "Ξ" },
+ { "Yacute", "Ý" },
+ { "Yuml", "Ÿ" },
+ { "Zeta", "Ζ" },
+ { "aacute", "á" },
+ { "acirc", "â" },
+ { "acute", "´" },
+ { "aelig", "æ" },
+ { "agrave", "à" },
+ { "alefsym", "ℵ" },
+ { "alpha", "α" },
+ { "amp", "&" },
+ { "and", "∧" },
+ { "ang", "∠" },
+ { "apos", "'" },
+ { "aring", "å" },
+ { "asymp", "≈" },
+ { "atilde", "ã" },
+ { "auml", "ä" },
+ { "bdquo", "„" },
+ { "beta", "β" },
+ { "brvbar", "¦" },
+ { "bull", "•" },
+ { "cap", "∩" },
+ { "ccedil", "ç" },
+ { "cedil", "¸" },
+ { "cent", "¢" },
+ { "chi", "χ" },
+ { "circ", "ˆ" },
+ { "clubs", "♣" },
+ { "cong", "≅" },
+ { "copy", "©" },
+ { "crarr", "↵" },
+ { "cup", "∪" },
+ { "curren", "¤" },
+ { "dArr", "⇓" },
+ { "dagger", "†" },
+ { "darr", "↓" },
+ { "deg", "°" },
+ { "delta", "δ" },
+ { "diams", "♦" },
+ { "divide", "÷" },
+ { "eacute", "é" },
+ { "ecirc", "ê" },
+ { "egrave", "è" },
+ { "empty", "∅" },
+ { "emsp", " " },
+ { "ensp", " " },
+ { "epsilon", "ε" },
+ { "equiv", "≡" },
+ { "eta", "η" },
+ { "eth", "ð" },
+ { "euml", "ë" },
+ { "euro", "€" },
+ { "exist", "∃" },
+ { "fnof", "ƒ" },
+ { "forall", "∀" },
+ { "frac12", "½" },
+ { "frac14", "¼" },
+ { "frac34", "¾" },
+ { "frasl", "⁄" },
+ { "gamma", "γ" },
+ { "ge", "≥" },
+ { "gt", ">" },
+ { "hArr", "⇔" },
+ { "harr", "↔" },
+ { "hearts", "♥" },
+ { "hellip", "…" },
+ { "iacute", "í" },
+ { "icirc", "î" },
+ { "iexcl", "¡" },
+ { "igrave", "ì" },
+ { "image", "ℑ" },
+ { "infin", "∞" },
+ { "int", "∫" },
+ { "iota", "ι" },
+ { "iquest", "¿" },
+ { "isin", "∈" },
+ { "iuml", "ï" },
+ { "kappa", "κ" },
+ { "lArr", "⇐" },
+ { "lambda", "λ" },
+ { "lang", "〈" },
+ { "laquo", "«" },
+ { "larr", "←" },
+ { "lceil", "⌈" },
+ { "ldquo", "“" },
+ { "le", "≤" },
+ { "lfloor", "⌊" },
+ { "lowast", "∗" },
+ { "loz", "◊" },
+ { "lrm", "\xE2\x80\x8E" },
+ { "lsaquo", "‹" },
+ { "lsquo", "‘" },
+ { "lt", "<" },
+ { "macr", "¯" },
+ { "mdash", "—" },
+ { "micro", "µ" },
+ { "middot", "·" },
+ { "minus", "−" },
+ { "mu", "μ" },
+ { "nabla", "∇" },
+ { "nbsp", " " },
+ { "ndash", "–" },
+ { "ne", "≠" },
+ { "ni", "∋" },
+ { "not", "¬" },
+ { "notin", "∉" },
+ { "nsub", "⊄" },
+ { "ntilde", "ñ" },
+ { "nu", "ν" },
+ { "oacute", "ó" },
+ { "ocirc", "ô" },
+ { "oelig", "œ" },
+ { "ograve", "ò" },
+ { "oline", "‾" },
+ { "omega", "ω" },
+ { "omicron", "ο" },
+ { "oplus", "⊕" },
+ { "or", "∨" },
+ { "ordf", "ª" },
+ { "ordm", "º" },
+ { "oslash", "ø" },
+ { "otilde", "õ" },
+ { "otimes", "⊗" },
+ { "ouml", "ö" },
+ { "para", "¶" },
+ { "part", "∂" },
+ { "permil", "‰" },
+ { "perp", "⊥" },
+ { "phi", "φ" },
+ { "pi", "π" },
+ { "piv", "ϖ" },
+ { "plusmn", "±" },
+ { "pound", "£" },
+ { "prime", "′" },
+ { "prod", "∏" },
+ { "prop", "∝" },
+ { "psi", "ψ" },
+ { "quot", "\"" },
+ { "rArr", "⇒" },
+ { "radic", "√" },
+ { "rang", "〉" },
+ { "raquo", "»" },
+ { "rarr", "→" },
+ { "rceil", "⌉" },
+ { "rdquo", "”" },
+ { "real", "ℜ" },
+ { "reg", "®" },
+ { "rfloor", "⌋" },
+ { "rho", "ρ" },
+ { "rlm", "\xE2\x80\x8F" },
+ { "rsaquo", "›" },
+ { "rsquo", "’" },
+ { "sbquo", "‚" },
+ { "scaron", "š" },
+ { "sdot", "⋅" },
+ { "sect", "§" },
+ { "shy", "\xC2\xAD" },
+ { "sigma", "σ" },
+ { "sigmaf", "ς" },
+ { "sim", "∼" },
+ { "spades", "♠" },
+ { "sub", "⊂" },
+ { "sube", "⊆" },
+ { "sum", "∑" },
+ { "sup", "⊃" },
+ { "sup1", "¹" },
+ { "sup2", "²" },
+ { "sup3", "³" },
+ { "supe", "⊇" },
+ { "szlig", "ß" },
+ { "tau", "τ" },
+ { "there4", "∴" },
+ { "theta", "θ" },
+ { "thetasym", "ϑ" },
+ { "thinsp", " " },
+ { "thorn", "þ" },
+ { "tilde", "˜" },
+ { "times", "×" },
+ { "trade", "™" },
+ { "uArr", "⇑" },
+ { "uacute", "ú" },
+ { "uarr", "↑" },
+ { "ucirc", "û" },
+ { "ugrave", "ù" },
+ { "uml", "¨" },
+ { "upsih", "ϒ" },
+ { "upsilon", "υ" },
+ { "uuml", "ü" },
+ { "weierp", "℘" },
+ { "xi", "ξ" },
+ { "yacute", "ý" },
+ { "yen", "¥" },
+ { "yuml", "ÿ" },
+ { "zeta", "ζ" },
+ { "zwj", "\xE2\x80\x8D" },
+ { "zwnj", "\xE2\x80\x8C" }
+};
+
+CMStringW RemoveHtml(const CMStringW &data)
+{
+ CMStringW new_string;
+
+ for (int i = 0; i < data.GetLength(); i++) {
+ wchar_t c = data[i];
+ if (c == '<') {
+ i = data.Find('>', i);
+ if (i == -1)
+ break;
+
+ continue;
+ }
+
+ // special character
+ if (c == '&') {
+ int begin = i;
+ i = data.Find(';', i);
+ if (i == -1)
+ i = begin;
+ else {
+ CMStringW entity = data.Mid(begin + 1, i - begin - 1);
+
+ bool found = false;
+ if (entity.GetLength() > 1 && entity[0] == '#') {
+ // Numeric replacement
+ bool hex = false;
+ if (entity[1] == 'x') {
+ hex = true;
+ entity.Delete(0, 2);
+ }
+ else entity.Delete(0, 1);
+
+ if (!entity.IsEmpty()) {
+ found = true;
+ errno = 0;
+ unsigned long value = wcstoul(entity, nullptr, hex ? 16 : 10);
+ if (errno != 0) { // error with conversion in strtoul, ignore the result
+ found = false;
+ }
+ else if (value <= 127) { // U+0000 .. U+007F
+ new_string += (char)value;
+ }
+ else if (value >= 128 && value <= 2047) { // U+0080 .. U+07FF
+ new_string += (char)(192 + (value / 64));
+ new_string += (char)(128 + (value % 64));
+ }
+ else if (value >= 2048 && value <= 65535) { // U+0800 .. U+FFFF
+ new_string += (char)(224 + (value / 4096));
+ new_string += (char)(128 + ((value / 64) % 64));
+ new_string += (char)(128 + (value % 64));
+ }
+ else {
+ new_string += (char)((value >> 24) & 0xFF);
+ new_string += (char)((value >> 16) & 0xFF);
+ new_string += (char)((value >> 8) & 0xFF);
+ new_string += (char)((value) & 0xFF);
+ }
+ }
+ }
+ else {
+ // Keyword replacement
+ CMStringA tmp = entity;
+ for (auto &it : htmlEntities) {
+ if (!mir_strcmpi(tmp, it.entity)) {
+ new_string += it.symbol;
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (found)
+ continue;
+ else
+ i = begin;
+ }
+ }
+
+ new_string.AppendChar(c);
+ }
+
+ return new_string;
+}
+
+const char* CSkypeProto::MirandaToSkypeStatus(int status)
+{
+ switch (status) {
+ case ID_STATUS_AWAY:
+ return "Away";
+
+ case ID_STATUS_DND:
+ return "Busy";
+
+ case ID_STATUS_IDLE:
+ return "Idle";
+
+ case ID_STATUS_INVISIBLE:
+ return "Hidden";
+ }
+ return "Online";
+}
+
+int CSkypeProto::SkypeToMirandaStatus(const char *status)
+{
+ if (!mir_strcmpi(status, "Online"))
+ return ID_STATUS_ONLINE;
+ else if (!mir_strcmpi(status, "Hidden"))
+ return ID_STATUS_INVISIBLE;
+ else if (!mir_strcmpi(status, "Away"))
+ return ID_STATUS_AWAY;
+ else if (!mir_strcmpi(status, "Idle"))
+ return ID_STATUS_AWAY;
+ else if (!mir_strcmpi(status, "Busy"))
+ return ID_STATUS_DND;
+ else
+ return ID_STATUS_OFFLINE;
+}
+
+bool CSkypeProto::IsFileExists(std::wstring path)
+{
+ return _waccess(path.c_str(), 0) == 0;
+}
+
+const char* GetSkypeNick(const char *szSkypeId)
+{
+ if (auto *p = strchr(szSkypeId, ':'))
+ return p + 1;
+ return szSkypeId;
+}
+
+const wchar_t* GetSkypeNick(const wchar_t *szSkypeId)
+{
+ if (auto *p = wcsrchr(szSkypeId, ':'))
+ return p + 1;
+ return szSkypeId;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// url parsing
+
+CMStringA ParseUrl(const char *url, const char *token)
+{
+ if (url == nullptr)
+ return CMStringA();
+
+ auto *start = strstr(url, token);
+ if (start == nullptr)
+ return CMStringA();
+
+ auto *end = strchr(++start, '/');
+ if (end == nullptr)
+ return CMStringA(start);
+ return CMStringA(start, end - start);
+}
+
+CMStringW ParseUrl(const wchar_t *url, const wchar_t *token)
+{
+ if (url == nullptr)
+ return CMStringW();
+
+ auto *start = wcsstr(url, token);
+ if (start == nullptr)
+ return CMStringW();
+
+ auto *end = wcschr(++start, '/');
+ if (end == nullptr)
+ return CMStringW(start);
+ return CMStringW(start, end - start);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+static int possibleTypes[] = { 1, 2, 8, 19 };
+
+CMStringA UrlToSkypeId(const char *url, int *pUserType)
+{
+ int userType = -1;
+ CMStringA szResult;
+
+ if (url != nullptr) {
+ for (auto &it : possibleTypes) {
+ char tmp[10];
+ sprintf_s(tmp, "/%d:", it);
+ if (strstr(url, tmp)) {
+ userType = it;
+ szResult = ParseUrl(url, tmp);
+ break;
+ }
+ }
+ }
+
+ if (pUserType)
+ *pUserType = userType;
+
+ return szResult;
+}
+
+CMStringW UrlToSkypeId(const wchar_t *url, int *pUserType)
+{
+ int userType = -1;
+ CMStringW szResult;
+
+ if (url != nullptr) {
+ for (auto &it : possibleTypes) {
+ wchar_t tmp[10];
+ swprintf_s(tmp, L"/%d:", it);
+ if (wcsstr(url, tmp)) {
+ userType = it;
+ szResult = ParseUrl(url, tmp);
+ break;
+ }
+ }
+ }
+
+ if (pUserType)
+ *pUserType = userType;
+
+ return szResult;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+INT_PTR CSkypeProto::ParseSkypeUriService(WPARAM, LPARAM lParam)
+{
+ wchar_t *arg = (wchar_t *)lParam;
+ if (arg == nullptr)
+ return 1;
+
+ // skip leading prefix
+ wchar_t szUri[1024];
+ wcsncpy_s(szUri, arg, _TRUNCATE);
+ wchar_t *szJid = wcschr(szUri, ':');
+ if (szJid == nullptr)
+ return 1;
+
+ // empty jid?
+ if (!*szJid)
+ return 1;
+
+ // command code
+ wchar_t *szCommand = szJid;
+ szCommand = wcschr(szCommand, '?');
+ if (szCommand)
+ *(szCommand++) = 0;
+
+ // parameters
+ wchar_t *szSecondParam = szCommand ? wcschr(szCommand, '&') : nullptr;
+ if (szSecondParam)
+ *(szSecondParam++) = 0;
+
+ // no command or message command
+ if (!szCommand || !mir_wstrcmpi(szCommand, L"chat")) {
+ if (szSecondParam) {
+ wchar_t *szChatId = wcsstr(szSecondParam, L"id=");
+ if (szChatId) {
+ szChatId += 5;
+ StartChatRoom(szChatId, szChatId);
+ return 0;
+ }
+ }
+ MCONTACT hContact = AddContact(_T2A(szJid), nullptr, true);
+ CallService(MS_MSG_SENDMESSAGE, (WPARAM)hContact, NULL);
+ return 0;
+ }
+
+ if (!mir_wstrcmpi(szCommand, L"call")) {
+ MCONTACT hContact = AddContact(_T2A(szJid), nullptr, true);
+ NotifyEventHooks(g_hCallEvent, (WPARAM)hContact, (LPARAM)0);
+ return 0;
+ }
+
+ if (!mir_wstrcmpi(szCommand, L"userinfo"))
+ return 0;
+
+ if (!mir_wstrcmpi(szCommand, L"add")) {
+ MCONTACT hContact = FindContact(_T2A(szJid));
+ if (hContact == NULL) {
+ PROTOSEARCHRESULT psr = { 0 };
+ psr.cbSize = sizeof(psr);
+ psr.id.w = mir_wstrdup(szJid);
+ psr.nick.w = mir_wstrdup(szJid);
+ psr.flags = PSR_UNICODE;
+ Contact::AddBySearch(m_szModuleName, &psr);
+ }
+ return 0;
+ }
+
+ if (!mir_wstrcmpi(szCommand, L"sendfile")) {
+ MCONTACT hContact = AddContact(_T2A(szJid), nullptr, true);
+ CallService(MS_FILE_SENDFILE, hContact, NULL);
+ return 1;
+ }
+
+ if (!mir_wstrcmpi(szCommand, L"voicemail"))
+ return 1;
+
+ return 1;
+}
+
+INT_PTR CSkypeProto::GlobalParseSkypeUriService(WPARAM wParam, LPARAM lParam)
+{
+ for (auto &it : CMPlugin::g_arInstances)
+ if (it->IsOnline())
+ return it->ParseSkypeUriService(wParam, lParam);
+
+ return 1;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+
+JsonReply::JsonReply(NETLIBHTTPREQUEST *pReply)
+{
+ if (pReply == nullptr) {
+ m_errorCode = 500;
+ return;
+ }
+
+ m_errorCode = pReply->resultCode;
+ if (m_errorCode != 200)
+ return;
+
+ m_root = json_parse(pReply->pData);
+ if (m_root == nullptr) {
+ m_errorCode = 500;
+ return;
+ }
+
+ m_errorCode = (*m_root)["status"]["code"].as_int();
+}
+
+JsonReply::~JsonReply()
+{
+ json_delete(m_root);
+}
diff --git a/protocols/SkypeWeb/src/skype_utils.h b/protocols/SkypeWeb/src/skype_utils.h index 6234abf8b6..e8a1f05836 100644 --- a/protocols/SkypeWeb/src/skype_utils.h +++ b/protocols/SkypeWeb/src/skype_utils.h @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/stdafx.cxx b/protocols/SkypeWeb/src/stdafx.cxx index f64d25234b..ebbde0ade1 100644 --- a/protocols/SkypeWeb/src/stdafx.cxx +++ b/protocols/SkypeWeb/src/stdafx.cxx @@ -1,5 +1,5 @@ /*
-Copyright (C) 2012-22 Miranda NG team (https://miranda-ng.org)
+Copyright (C) 2012-23 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
diff --git a/protocols/SkypeWeb/src/stdafx.h b/protocols/SkypeWeb/src/stdafx.h index 059d5cb9d6..6dbb1da1c3 100644 --- a/protocols/SkypeWeb/src/stdafx.h +++ b/protocols/SkypeWeb/src/stdafx.h @@ -1,5 +1,5 @@ /*
-Copyright (c) 2015-22 Miranda NG team (https://miranda-ng.org)
+Copyright (c) 2015-23 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
diff --git a/protocols/SkypeWeb/src/version.h b/protocols/SkypeWeb/src/version.h index b41d65df1e..991de1af6d 100644 --- a/protocols/SkypeWeb/src/version.h +++ b/protocols/SkypeWeb/src/version.h @@ -10,4 +10,4 @@ #define __DESCRIPTION "Skype protocol support for Miranda NG. Based on new Skype for Web."
#define __AUTHOR "Miranda NG team"
#define __AUTHORWEB "https://miranda-ng.org/p/SkypeWeb"
-#define __COPYRIGHT "© 2015-22 Miranda NG team"
+#define __COPYRIGHT "© 2015-23 Miranda NG team"
|