summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--protocols/SkypeWeb/SkypeWeb_12.vcxproj3
-rw-r--r--protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters9
-rw-r--r--protocols/SkypeWeb/src/common.h3
-rw-r--r--protocols/SkypeWeb/src/http_request.h81
-rw-r--r--protocols/SkypeWeb/src/requests/contacts.h30
-rw-r--r--protocols/SkypeWeb/src/requests/endpoint.h25
-rw-r--r--protocols/SkypeWeb/src/requests/login.h17
-rw-r--r--protocols/SkypeWeb/src/requests/logout.h7
-rw-r--r--protocols/SkypeWeb/src/requests/profile.h6
-rw-r--r--protocols/SkypeWeb/src/requests/reg_info.h23
-rw-r--r--protocols/SkypeWeb/src/requests/status.h26
-rw-r--r--protocols/SkypeWeb/src/skype_events.cpp32
-rw-r--r--protocols/SkypeWeb/src/skype_proto.cpp9
-rw-r--r--protocols/SkypeWeb/src/skype_proto.h5
-rw-r--r--protocols/SkypeWeb/src/skype_utils.cpp20
15 files changed, 249 insertions, 47 deletions
diff --git a/protocols/SkypeWeb/SkypeWeb_12.vcxproj b/protocols/SkypeWeb/SkypeWeb_12.vcxproj
index d24592227f..4066989050 100644
--- a/protocols/SkypeWeb/SkypeWeb_12.vcxproj
+++ b/protocols/SkypeWeb/SkypeWeb_12.vcxproj
@@ -204,9 +204,12 @@
<ClInclude Include="src\common.h" />
<ClInclude Include="src\http_request.h" />
<ClInclude Include="src\requests\contacts.h" />
+ <ClInclude Include="src\requests\endpoint.h" />
<ClInclude Include="src\requests\login.h" />
<ClInclude Include="src\requests\logout.h" />
<ClInclude Include="src\requests\profile.h" />
+ <ClInclude Include="src\requests\reg_info.h" />
+ <ClInclude Include="src\requests\status.h" />
<ClInclude Include="src\resource.h" />
<ClInclude Include="src\skype_icons.h" />
<ClInclude Include="src\skype_menus.h" />
diff --git a/protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters b/protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters
index 8d6e04a255..37d2954121 100644
--- a/protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters
+++ b/protocols/SkypeWeb/SkypeWeb_12.vcxproj.filters
@@ -54,6 +54,15 @@
<ClInclude Include="src\requests\profile.h">
<Filter>Header Files\requests</Filter>
</ClInclude>
+ <ClInclude Include="src\requests\endpoint.h">
+ <Filter>Header Files\requests</Filter>
+ </ClInclude>
+ <ClInclude Include="src\requests\reg_info.h">
+ <Filter>Header Files\requests</Filter>
+ </ClInclude>
+ <ClInclude Include="src\requests\status.h">
+ <Filter>Header Files\requests</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\stdafx.cpp">
diff --git a/protocols/SkypeWeb/src/common.h b/protocols/SkypeWeb/src/common.h
index afd15659c4..6a604be5b0 100644
--- a/protocols/SkypeWeb/src/common.h
+++ b/protocols/SkypeWeb/src/common.h
@@ -47,6 +47,9 @@ struct CSkypeProto;
#include "requests\logout.h"
#include "requests\profile.h"
#include "requests\contacts.h"
+#include "requests\status.h"
+#include "requests\reg_info.h"
+#include "requests\endpoint.h"
#include "request_queue.h"
#include "skype_proto.h"
diff --git a/protocols/SkypeWeb/src/http_request.h b/protocols/SkypeWeb/src/http_request.h
index 28b34c075d..5d34d04e3f 100644
--- a/protocols/SkypeWeb/src/http_request.h
+++ b/protocols/SkypeWeb/src/http_request.h
@@ -171,19 +171,14 @@ protected:
HttpRequest() : Headers(*this)
{
cbSize = sizeof(NETLIBHTTPREQUEST);
+ flags = NLHRF_HTTP11 | NLHRF_NODUMPSEND | NLHRF_DUMPASTEXT;
}
HttpRequest(int httpMethod, LPCSTR urlFormat, va_list args)
: Headers(*this)
{
- this->HttpRequest::HttpRequest();
-
requestType = httpMethod;
- flags = NLHRF_HTTP11 | NLHRF_NODUMPSEND | NLHRF_DUMPASTEXT;
-
Url.content.AppendFormatV(urlFormat, args);
- if (Url.content.Find("://") == -1)
- Url.content.Insert(0, flags & NLHRF_SSL ? "https://" : "http://");
}
public:
@@ -213,6 +208,8 @@ public:
NETLIBHTTPREQUEST * Send(HANDLE hConnection)
{
+ if (Url.content.Find("://") == -1)
+ Url.content.Insert(0, flags & NLHRF_SSL ? "https://" : "http://");
szUrl = Url.ToString();
pData = Body.ToString();
@@ -226,4 +223,76 @@ public:
}
};
+class HttpGetRequest : public HttpRequest
+{
+public:
+ HttpGetRequest(LPCSTR urlFormat, ...)
+ {
+ va_list args;
+ va_start(args, urlFormat);
+ this->HttpRequest::HttpRequest(REQUEST_GET, urlFormat, args);
+ va_end(args);
+ }
+};
+
+class HttpPostRequest : public HttpRequest
+{
+public:
+ HttpPostRequest(LPCSTR urlFormat, ...)
+ {
+ va_list args;
+ va_start(args, urlFormat);
+ this->HttpRequest::HttpRequest(REQUEST_POST, urlFormat, args);
+ va_end(args);
+
+ Headers << CHAR_VALUE("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
+ }
+};
+
+class HttpsRequest : public HttpRequest
+{
+protected:
+ HttpsRequest() : HttpRequest()
+ {
+ flags = NLHRF_HTTP11 | NLHRF_SSL | NLHRF_NODUMPSEND | NLHRF_DUMPASTEXT;
+ }
+
+public:
+ HttpsRequest(int type, LPCSTR urlFormat, ...)
+ {
+ va_list args;
+ va_start(args, urlFormat);
+ this->HttpRequest::HttpRequest(type, urlFormat, args);
+ va_end(args);
+
+ flags = NLHRF_HTTP11 | NLHRF_SSL | NLHRF_NODUMPSEND | NLHRF_DUMPASTEXT;
+ }
+};
+
+class HttpsGetRequest : public HttpsRequest
+{
+public:
+ HttpsGetRequest(LPCSTR urlFormat, ...)
+ {
+ va_list args;
+ va_start(args, urlFormat);
+ this->HttpRequest::HttpRequest(REQUEST_GET, urlFormat, args);
+ va_end(args);
+ }
+};
+
+class HttpsPostRequest : public HttpsRequest
+{
+public:
+ HttpsPostRequest(LPCSTR urlFormat, ...)
+ {
+ va_list args;
+ va_start(args, urlFormat);
+ this->HttpsRequest::HttpsRequest(REQUEST_POST, urlFormat, args);
+ va_end(args);
+
+ Headers << CHAR_VALUE("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
+ }
+};
+
#endif //_HTTP_REQUEST_H_ \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/requests/contacts.h b/protocols/SkypeWeb/src/requests/contacts.h
index aff095df65..96c0b1c203 100644
--- a/protocols/SkypeWeb/src/requests/contacts.h
+++ b/protocols/SkypeWeb/src/requests/contacts.h
@@ -1,14 +1,12 @@
#ifndef _SKYPE_REQUEST_CONTACTS_H_
#define _SKYPE_REQUEST_CONTACTS_H_
-class GetContactListRequest : public HttpRequest
+class GetContactListRequest : public HttpsGetRequest
{
public:
GetContactListRequest(const char *token, const char *skypename = "self") :
- HttpRequest(REQUEST_GET, "api.skype.com/users/%s/contacts?hideDetails=true", skypename)
+ HttpsGetRequest("api.skype.com/users/%s/contacts", skypename)
{
- flags |= NLHRF_SSL;
-
Url << CHAR_VALUE("hideDetails", "true");
Headers
@@ -18,14 +16,12 @@ public:
}
};
-class GetContactsInfoRequest : public HttpRequest
+class GetContactsInfoRequest : public HttpsPostRequest
{
public:
GetContactsInfoRequest(const char *token, const LIST<char> &skypenames, const char *skypename = "self") :
- HttpRequest(REQUEST_POST, "api.skype.com/users/%s/contacts/profiles", skypename)
+ HttpsPostRequest("api.skype.com/users/%s/contacts/profiles", skypename)
{
- flags |= NLHRF_SSL;
-
Headers
<< CHAR_VALUE("X-Skypetoken", "Accept")
<< CHAR_VALUE("X-Skypetoken", token)
@@ -38,42 +34,36 @@ public:
}
};
-class GetContactsAuthRequest : public HttpRequest
+class GetContactsAuthRequest : public HttpsGetRequest
{
public:
GetContactsAuthRequest(const char *token, const char *skypename = "self") :
- HttpRequest(REQUEST_GET, "api.skype.com/users/%s/contacts/auth-request", skypename)
+ HttpsGetRequest("api.skype.com/users/%s/contacts/auth-request", skypename)
{
- flags |= NLHRF_SSL;
-
Headers
<< CHAR_VALUE("X-Skypetoken", token)
<< CHAR_VALUE("Accept", "application/json");
}
};
-class AuthAcceptRequest : public HttpRequest
+class AuthAcceptRequest : public HttpsGetRequest
{
public:
AuthAcceptRequest(const char *token, const char *who, const char *skypename = "self") :
- HttpRequest(REQUEST_GET, "api.skype.com/users/%s/contacts/auth-request/%s/accept", skypename, who)
+ HttpsGetRequest("api.skype.com/users/%s/contacts/auth-request/%s/accept", skypename, who)
{
- flags |= NLHRF_SSL;
-
Headers
<< CHAR_VALUE("X-Skypetoken", token)
<< CHAR_VALUE("Accept", "application/json");
}
};
-class AuthDeclineRequest : public HttpRequest
+class AuthDeclineRequest : public HttpsGetRequest
{
public:
AuthDeclineRequest(const char *token, const char *who, const char *skypename = "self") :
- HttpRequest(REQUEST_GET, "api.skype.com/users/%s/contacts/auth-request/%s/decline", skypename)
+ HttpsGetRequest("api.skype.com/users/%s/contacts/auth-request/%s/decline", skypename)
{
- flags |= NLHRF_SSL;
-
Headers
<< CHAR_VALUE("X-Skypetoken", token)
<< CHAR_VALUE("Accept", "application/json");
diff --git a/protocols/SkypeWeb/src/requests/endpoint.h b/protocols/SkypeWeb/src/requests/endpoint.h
new file mode 100644
index 0000000000..a6878f3f1f
--- /dev/null
+++ b/protocols/SkypeWeb/src/requests/endpoint.h
@@ -0,0 +1,25 @@
+#ifndef _SKYPE_REQUEST_ENDPOINT_H_
+#define _SKYPE_REQUEST_ENDPOINT_H_
+
+class GetEndpointRequest : public HttpsRequest
+{
+public:
+ GetEndpointRequest(const char *regToken, const char *endpointURL) :
+ HttpsRequest(REQUEST_PUT, endpointURL)
+ {
+ flags |= NLHRF_SSL;
+
+ Headers
+ << CHAR_VALUE("Accept", "application/json, text/javascript")
+ << CHAR_VALUE("Expires", "0")
+ << FORMAT_VALUE("RegistrationToken", "registrationToken=%s", regToken)
+ << CHAR_VALUE("Content-Type", "application/json; charset=UTF-8")
+ << CHAR_VALUE("Referer", "https://web.skype.com/main")
+ << CHAR_VALUE("Origin", "https://web.skype.com")
+ << CHAR_VALUE("Connection", "keep-alive");
+
+ Body <<
+ VALUE("{\"id\":\"messagingService\",\"type\":\"EndpointPresenceDoc\",\"selfLink\":\"uri\",\"privateInfo\":{\"epname\":\"skype\"},\"publicInfo\":{\"capabilities\":\"video | audio\",\"type\":1,\"skypeNameVersion\":\"908 / 1.0.30 / swx - skype.com\",\"nodeInfo\":\"xx\",\"version\":\"908 / 1.0.30\"}}");
+ }
+};
+#endif //_SKYPE_REQUEST_ENDPOINT_H_ \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/requests/login.h b/protocols/SkypeWeb/src/requests/login.h
index 12f0e9e5cc..8c45c7237c 100644
--- a/protocols/SkypeWeb/src/requests/login.h
+++ b/protocols/SkypeWeb/src/requests/login.h
@@ -1,30 +1,29 @@
#ifndef _SKYPE_REQUEST_LOGIN_H_
#define _SKYPE_REQUEST_LOGIN_H_
-class LoginRequest : public HttpRequest
+class LoginRequest : public HttpsPostRequest
{
public:
LoginRequest() :
- HttpRequest(REQUEST_POST, "login.skype.com/login")
+ HttpsPostRequest("login.skype.com/login")
{
- flags |= NLHRF_SSL;
-
Url
<< INT_VALUE("client_id", 578134)
<< CHAR_VALUE("redirect_uri", "https%3A%2F%2Fweb.skype.com");
Headers
- << CHAR_VALUE("Host", "login.skype.com")
- << CHAR_VALUE("Referer", "https://web.skype.com/");
+ << CHAR_VALUE("Host", "login.skype.com");
}
LoginRequest(const char *skypename, const char *password, const char *pie, const char *etm) :
- HttpRequest(REQUEST_POST, "login.skype.com/login")
+ HttpsPostRequest("login.skype.com/login")
{
- this->LoginRequest::LoginRequest();
+ Url
+ << INT_VALUE("client_id", 578134)
+ << CHAR_VALUE("redirect_uri", "https%3A%2F%2Fweb.skype.com");
Headers
- << CHAR_VALUE("Content-Type", "application/x-www-form-urlencoded")
+ << CHAR_VALUE("Host", "login.skype.com")
<< CHAR_VALUE("Referer", "https://login.skype.com/login?method=skype&client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com");
LPTIME_ZONE_INFORMATION tzi = tmi.getTziByContact(NULL);
diff --git a/protocols/SkypeWeb/src/requests/logout.h b/protocols/SkypeWeb/src/requests/logout.h
index 60f30e639c..b1585c9e91 100644
--- a/protocols/SkypeWeb/src/requests/logout.h
+++ b/protocols/SkypeWeb/src/requests/logout.h
@@ -1,13 +1,10 @@
#ifndef _SKYPE_REQUEST_LOGOUT_H_
#define _SKYPE_REQUEST_LOGOUT_H_
-class LogoutRequest : public HttpRequest
+class LogoutRequest : public HttpsPostRequest
{
public:
- LogoutRequest() : HttpRequest(REQUEST_POST, "login.skype.com/logout")
- {
- flags |= NLHRF_SSL;
- }
+ LogoutRequest() : HttpsPostRequest("login.skype.com/logout") { }
};
#endif //_SKYPE_REQUEST_LOGOUT_H_
diff --git a/protocols/SkypeWeb/src/requests/profile.h b/protocols/SkypeWeb/src/requests/profile.h
index 2c0b4e8fb6..579ac446b4 100644
--- a/protocols/SkypeWeb/src/requests/profile.h
+++ b/protocols/SkypeWeb/src/requests/profile.h
@@ -1,14 +1,12 @@
#ifndef _SKYPE_REQUEST_PROFILE_H_
#define _SKYPE_REQUEST_PROFILE_H_
-class GetProfileRequest : public HttpRequest
+class GetProfileRequest : public HttpsGetRequest
{
public:
GetProfileRequest(const char *token, const char *skypename = "self") :
- HttpRequest(REQUEST_GET, "api.skype.com/users/%s/profile", skypename)
+ HttpsGetRequest("api.skype.com/users/%s/profile", skypename)
{
- flags |= NLHRF_SSL;
-
Headers
<< CHAR_VALUE("X-Skypetoken", token)
<< CHAR_VALUE("Accept", "application/json");
diff --git a/protocols/SkypeWeb/src/requests/reg_info.h b/protocols/SkypeWeb/src/requests/reg_info.h
new file mode 100644
index 0000000000..6ba0518524
--- /dev/null
+++ b/protocols/SkypeWeb/src/requests/reg_info.h
@@ -0,0 +1,23 @@
+#ifndef _SKYPE_REQUEST_REGINFO_H_
+#define _SKYPE_REQUEST_REGINFO_H_
+
+class GetRegInfoRequest : public HttpsPostRequest
+{
+public:
+ GetRegInfoRequest(const char *token) :
+ HttpsPostRequest("client-s.gateway.messenger.live.com/v1/users/ME/endpoints")
+ {
+ Headers
+ << CHAR_VALUE("Accept", "application/json, text/javascript")
+ << CHAR_VALUE("Expires", "0")
+ << FORMAT_VALUE("Authentication", "skypetoken=%s", token)
+ << CHAR_VALUE("Content-Type", "application/json; charset = UTF-8")
+ << CHAR_VALUE("Referer", "https://web.skype.com/main")
+ << CHAR_VALUE("Origin", "https://web.skype.com")
+ << CHAR_VALUE("Connection", "keep-alive");
+
+ Body << VALUE("{}");
+ }
+};
+
+#endif //_SKYPE_REQUEST_STATUS_H_
diff --git a/protocols/SkypeWeb/src/requests/status.h b/protocols/SkypeWeb/src/requests/status.h
new file mode 100644
index 0000000000..07703e84ae
--- /dev/null
+++ b/protocols/SkypeWeb/src/requests/status.h
@@ -0,0 +1,26 @@
+#ifndef _SKYPE_REQUEST_STATUS_H_
+#define _SKYPE_REQUEST_STATUS_H_
+
+class SetStatusRequest : public HttpsRequest
+{
+public:
+ SetStatusRequest(const char *regToken, bool status) :
+ HttpsRequest(REQUEST_PUT, "client-s.gateway.messenger.live.com/v1/users/ME/presenceDocs/messagingService")
+ {
+ Headers
+ << CHAR_VALUE("Accept", "application / json, text / javascript")
+ << CHAR_VALUE("Expires", "0")
+ << FORMAT_VALUE("RegistrationToken", "registrationToken=%s", regToken)
+ << CHAR_VALUE("Content-Type", "application/json; charset = UTF-8")
+ << CHAR_VALUE("Referer", "https://web.skype.com/main")
+ << CHAR_VALUE("Origin", "https://web.skype.com")
+ << CHAR_VALUE("Connection", "keep-alive");
+
+ const char *data = status
+ ? "{\"status\":\"Online\"}"
+ : "{\"status\":\"Hidden\"}";
+ Body << VALUE(data);
+ }
+};
+
+#endif //_SKYPE_REQUEST_STATUS_H_
diff --git a/protocols/SkypeWeb/src/skype_events.cpp b/protocols/SkypeWeb/src/skype_events.cpp
index 5139642270..309110b285 100644
--- a/protocols/SkypeWeb/src/skype_events.cpp
+++ b/protocols/SkypeWeb/src/skype_events.cpp
@@ -89,8 +89,40 @@ void CSkypeProto::OnLoginSecond(const NETLIBHTTPREQUEST *response)
cookies[match[1]] = match[2];
}
+ PushRequest(new GetRegInfoRequest(token.c_str()), &CSkypeProto::OnGetRegInfo);
PushRequest(new GetProfileRequest(token.c_str()), &CSkypeProto::LoadProfile);
PushRequest(new GetContactListRequest(token.c_str()), &CSkypeProto::LoadContactList);
ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, m_iStatus = m_iDesiredStatus);
+}
+
+void CSkypeProto::OnGetRegInfo(const NETLIBHTTPREQUEST *response)
+{
+ std::regex regex;
+ std::smatch match;
+ std::string content = response->pData;
+ for (int i = 0; i < response->headersCount; i++)
+ {
+ if (mir_strcmpi(response->headers[i].szName, "Set-RegistrationToken"))
+ continue;
+
+ regex = "^(.+?)=(.+?);";
+ content = response->headers[i].szValue;
+
+ if (std::regex_search(content, match, regex))
+ RegInfo[match[1]] = match[2];
+ }
+ setString("RegistrationToken", RegInfo["registrationToken"].c_str());
+
+ for (int i = 0; i < response->headersCount; i++)
+ {
+ if (mir_strcmpi(response->headers[i].szName, "Location"))
+ continue;
+ content = response->headers[i].szValue;
+ }
+ setString("Endpoint", urlDecode(content.c_str()).c_str());
+ debugLogA(getStringA("RegistrationToken"));
+ debugLogA(getStringA("Endpoint"));
+ PushRequest(new GetEndpointRequest(ptrA(getStringA("RegistrationToken")), ptrA(getStringA("Endpoint"))));
+ PushRequest(new SetStatusRequest(ptrA(getStringA("RegistrationToken")), true));
} \ No newline at end of file
diff --git a/protocols/SkypeWeb/src/skype_proto.cpp b/protocols/SkypeWeb/src/skype_proto.cpp
index b566b1c245..82a3ec1b00 100644
--- a/protocols/SkypeWeb/src/skype_proto.cpp
+++ b/protocols/SkypeWeb/src/skype_proto.cpp
@@ -33,9 +33,9 @@ DWORD_PTR CSkypeProto::GetCaps(int type, MCONTACT)
case PFLAGNUM_1:
return PF1_AUTHREQ;
case PFLAGNUM_2:
- return PF2_ONLINE;
+ return PF2_ONLINE | PF2_INVISIBLE;
case PFLAGNUM_3:
- return PF2_ONLINE;
+ return PF2_ONLINE | PF2_INVISIBLE;
case PFLAGNUM_4:
return PF4_FORCEADDED | PF4_NOAUTHDENYREASON;
case PFLAG_UNIQUEIDTEXT:
@@ -147,6 +147,11 @@ int CSkypeProto::SetStatus(int iNewStatus)
m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE;
}
+ else if (iNewStatus == ID_STATUS_INVISIBLE)
+ {
+ PushRequest(new GetEndpointRequest(ptrA(getStringA("RegistrationToken")), ptrA(getStringA("Endpoint"))));
+ PushRequest(new SetStatusRequest(ptrA(getStringA("RegistrationToken")), false));
+ }
else
{
if (old_status == ID_STATUS_CONNECTING)
diff --git a/protocols/SkypeWeb/src/skype_proto.h b/protocols/SkypeWeb/src/skype_proto.h
index dfe9aa87eb..4310050bad 100644
--- a/protocols/SkypeWeb/src/skype_proto.h
+++ b/protocols/SkypeWeb/src/skype_proto.h
@@ -83,6 +83,7 @@ private:
char *password;
RequestQueue *requestQueue;
std::map<std::string, std::string> cookies;
+ std::map<std::string, std::string> RegInfo;
static std::map<std::tstring, std::tstring> languages;
@@ -120,9 +121,10 @@ private:
// events
void OnLoginFirst(const NETLIBHTTPREQUEST *response);
-
void OnLoginSecond(const NETLIBHTTPREQUEST *response);
+ void OnGetRegInfo(const NETLIBHTTPREQUEST *response);
+
// profile
void UpdateProfileFirstName(JSONNODE *root, MCONTACT hContact = NULL);
void UpdateProfileLastName(JSONNODE *root, MCONTACT hContact = NULL);
@@ -174,6 +176,7 @@ private:
static void ShowNotification(const TCHAR *caption, const TCHAR *message, int flags = 0, MCONTACT hContact = NULL);
static bool IsFileExists(std::tstring path);
+ std::string urlDecode(std::string SRC);
template<INT_PTR(__cdecl CSkypeProto::*Service)(WPARAM, LPARAM)>
static INT_PTR __cdecl GlobalService(WPARAM wParam, LPARAM lParam)
diff --git a/protocols/SkypeWeb/src/skype_utils.cpp b/protocols/SkypeWeb/src/skype_utils.cpp
index 5ce367f768..a9a44e1c27 100644
--- a/protocols/SkypeWeb/src/skype_utils.cpp
+++ b/protocols/SkypeWeb/src/skype_utils.cpp
@@ -37,4 +37,24 @@ bool CSkypeProto::IsFileExists(std::tstring path)
return true;
}
return false;
+}
+
+std::string CSkypeProto::urlDecode(std::string SRC)
+{
+ std::string ret;
+ char ch;
+ int i, ii;
+ for (i = 0; i < SRC.length(); i++)
+ {
+ if (int(SRC[i]) == 37)
+ {
+ sscanf(SRC.substr(i + 1, 2).c_str(), "%x", &ii);
+ ch = static_cast<char>(ii);
+ ret += ch;
+ i = i + 2;
+ }
+ else
+ ret += SRC[i];
+ }
+ return (ret);
} \ No newline at end of file