summaryrefslogtreecommitdiff
path: root/protocols/SkypeWeb
diff options
context:
space:
mode:
authordartraiden <wowemuh@gmail.com>2023-01-02 21:10:29 +0300
committerdartraiden <wowemuh@gmail.com>2023-01-02 21:10:29 +0300
commit1979fd80424d16b2e489f9b57d01d9c7811d25a2 (patch)
tree960d42c5fe4a51f0fe2850bea91256e226bce221 /protocols/SkypeWeb
parentadfbbb217d4f4a05acf198755f219a5223d31c27 (diff)
Update copyrights
Diffstat (limited to 'protocols/SkypeWeb')
-rw-r--r--protocols/SkypeWeb/src/main.cpp2
-rw-r--r--protocols/SkypeWeb/src/request_queue.cpp2
-rw-r--r--protocols/SkypeWeb/src/requests/avatars.h2
-rw-r--r--protocols/SkypeWeb/src/requests/capabilities.h2
-rw-r--r--protocols/SkypeWeb/src/requests/chatrooms.h2
-rw-r--r--protocols/SkypeWeb/src/requests/contacts.h2
-rw-r--r--protocols/SkypeWeb/src/requests/endpoint.h2
-rw-r--r--protocols/SkypeWeb/src/requests/history.h2
-rw-r--r--protocols/SkypeWeb/src/requests/login.h2
-rw-r--r--protocols/SkypeWeb/src/requests/messages.h2
-rw-r--r--protocols/SkypeWeb/src/requests/oauth.h148
-rw-r--r--protocols/SkypeWeb/src/requests/poll.h2
-rw-r--r--protocols/SkypeWeb/src/requests/profile.h2
-rw-r--r--protocols/SkypeWeb/src/requests/search.h2
-rw-r--r--protocols/SkypeWeb/src/requests/status.h2
-rw-r--r--protocols/SkypeWeb/src/requests/subscriptions.h2
-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.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_db.cpp238
-rw-r--r--protocols/SkypeWeb/src/skype_db.h2
-rw-r--r--protocols/SkypeWeb/src/skype_events.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_history_sync.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_icons.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_login.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_menus.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_menus.h2
-rw-r--r--protocols/SkypeWeb/src/skype_messages.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_oauth.cpp330
-rw-r--r--protocols/SkypeWeb/src/skype_options.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_polling.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_profile.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_proto.cpp686
-rw-r--r--protocols/SkypeWeb/src/skype_proto.h2
-rw-r--r--protocols/SkypeWeb/src/skype_search.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_trouter.cpp2
-rw-r--r--protocols/SkypeWeb/src/skype_utils.cpp1358
-rw-r--r--protocols/SkypeWeb/src/skype_utils.h2
-rw-r--r--protocols/SkypeWeb/src/stdafx.cxx2
-rw-r--r--protocols/SkypeWeb/src/stdafx.h2
-rw-r--r--protocols/SkypeWeb/src/version.h2
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", &timestamp.tm_hour, &timestamp.tm_min, &timestamp.tm_sec) != 3)
- return (time_t)0;
-
- timestamp.tm_isdst = 0; // DST is already present in _timezone below
- time_t t = mktime(&timestamp);
-
- _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", &timestamp.tm_hour, &timestamp.tm_min, &timestamp.tm_sec) != 3)
+ return (time_t)0;
+
+ timestamp.tm_isdst = 0; // DST is already present in _timezone below
+ time_t t = mktime(&timestamp);
+
+ _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"