summaryrefslogtreecommitdiff
path: root/protocols/Skype/src
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Skype/src')
-rw-r--r--protocols/Skype/src/skype.cpp7
-rw-r--r--protocols/Skype/src/skype_account.cpp333
-rw-r--r--protocols/Skype/src/skype_avatars.cpp218
-rw-r--r--protocols/Skype/src/skype_chat.cpp15
-rw-r--r--protocols/Skype/src/skype_dialogs.cpp4
-rw-r--r--protocols/Skype/src/skype_events.cpp15
-rw-r--r--protocols/Skype/src/skype_hooks.cpp31
-rw-r--r--protocols/Skype/src/skype_instances.cpp5
-rw-r--r--protocols/Skype/src/skype_menus.cpp6
-rw-r--r--protocols/Skype/src/skype_netlib.cpp57
-rw-r--r--protocols/Skype/src/skype_proto.cpp54
-rw-r--r--protocols/Skype/src/skype_proto.h74
-rw-r--r--protocols/Skype/src/skype_services.cpp138
-rw-r--r--protocols/Skype/src/skype_utils.cpp339
-rw-r--r--protocols/Skype/src/skypekit/conversation.cpp10
-rw-r--r--protocols/Skype/src/skypekit/conversation.h4
-rw-r--r--protocols/Skype/src/skypekit/participant.cpp29
-rw-r--r--protocols/Skype/src/skypekit/participant.h3
18 files changed, 606 insertions, 736 deletions
diff --git a/protocols/Skype/src/skype.cpp b/protocols/Skype/src/skype.cpp
index a44eed5518..26ef149162 100644
--- a/protocols/Skype/src/skype.cpp
+++ b/protocols/Skype/src/skype.cpp
@@ -295,16 +295,19 @@ extern "C" int __declspec(dllexport) Load(void)
CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM)&pd);
CSkypeProto::InitIcons();
- CSkypeProto::InitServiceList();
CSkypeProto::InitMenus();
+ CSkypeProto::InitHookList();
+ CSkypeProto::InitServiceList();
return 0;
}
extern "C" int __declspec(dllexport) Unload(void)
{
- CSkypeProto::UninitMenus();
+ CSkypeProto::UninitServiceList();
+ CSkypeProto::UninitHookList();
CSkypeProto::UninitIcons();
+ CSkypeProto::UninitMenus();
g_skype->stop();
delete g_skype;
diff --git a/protocols/Skype/src/skype_account.cpp b/protocols/Skype/src/skype_account.cpp
index ac7149a945..5fd173ef1b 100644
--- a/protocols/Skype/src/skype_account.cpp
+++ b/protocols/Skype/src/skype_account.cpp
@@ -1,108 +1,54 @@
#include "skype_proto.h"
+#include "base64/base64.h"
-void CSkypeProto::OnAccountChanged(int prop)
+wchar_t *CSkypeProto::LogoutReasons[] =
{
- switch(prop)
- {
- case CAccount::P_STATUS:
- CAccount::STATUS loginStatus;
- this->account->GetPropStatus(loginStatus);
-
- if (loginStatus == CAccount::LOGGED_IN)
- {
- this->ForkThread(&CSkypeProto::SignInAsync, 0);
- //this->SignInAsync(this);
- }
-
- if (loginStatus == CAccount::LOGGED_OUT)
- {
- CAccount::LOGOUTREASON whyLogout;
- if (!this->account->GetPropLogoutreason(whyLogout))
- break;
-
- if (whyLogout != CAccount::LOGOUT_CALLED)
- {
- this->m_iStatus = ID_STATUS_OFFLINE;
- this->SendBroadcast(
- ACKTYPE_LOGIN, ACKRESULT_FAILED,
- NULL, this->SkypeToMirandaLoginError(whyLogout));
-
- this->ShowNotification(CSkypeProto::LogoutReasons[whyLogout - 1]);
-
- if (this->rememberPassword && whyLogout == CAccount::INCORRECT_PASSWORD)
- {
- this->rememberPassword = false;
- if (this->password)
- {
- ::mir_free(this->password);
- this->password = NULL;
- }
- }
- }
- }
- break;
-
- case CAccount::P_PWDCHANGESTATUS:
- {
- CAccount::PWDCHANGESTATUS status;
- this->account->GetPropPwdchangestatus(status);
- if (status != CAccount::PWD_CHANGING)
- this->ShowNotification(CSkypeProto::PasswordChangeReasons[status]);
- }
- break;
-
- //case CAccount::P_AVATAR_IMAGE:
- case CAccount::P_AVATAR_TIMESTAMP:
- this->UpdateProfileAvatar(this->account.fetch());
- break;
-
- //case CAccount::P_MOOD_TEXT:
- case CAccount::P_MOOD_TIMESTAMP:
- this->UpdateProfileStatusMessage(this->account.fetch());
- break;
-
- case CAccount::P_PROFILE_TIMESTAMP:
- this->UpdateProfile(this->account.fetch());
- break;
-
- /*case CAccount::P_AVAILABILITY:
- {
- CContact::AVAILABILITY status;
- this->account->GetPropAvailability(status);
- if (status != CContact::CONNECTING && status >= CContact::ONLINE)
- this->SetStatus(this->SkypeToMirandaStatus(status));
- }
- break;*/
- }
-}
+ LPGENW("LOGOUT_CALLED") /* LOGOUT_CALLED */,
+ LPGENW("HTTPS_PROXY_AUTH_FAILED") /* HTTPS_PROXY_AUTH_FAILED */,
+ LPGENW("SOCKS_PROXY_AUTH_FAILED") /* SOCKS_PROXY_AUTH_FAILED */,
+ LPGENW("P2P_CONNECT_FAILED") /* P2P_CONNECT_FAILED */,
+ LPGENW("SERVER_CONNECT_FAILED") /* SERVER_CONNECT_FAILED */,
+ LPGENW("SERVER_OVERLOADED") /* SERVER_OVERLOADED */,
+ LPGENW("DB_IN_USE") /* DB_IN_USE */,
+ LPGENW("Invalid skypename") /* INVALID_SKYPENAME */,
+ LPGENW("Invalid email") /* INVALID_EMAIL */,
+ LPGENW("Unacceptable password") /* UNACCEPTABLE_PASSWORD */,
+ LPGENW("SKYPENAME_TAKEN") /* SKYPENAME_TAKEN */,
+ LPGENW("REJECTED_AS_UNDERAGE") /* REJECTED_AS_UNDERAGE */,
+ LPGENW("NO_SUCH_IDENTITY") /* NO_SUCH_IDENTITY */,
+ LPGENW("Incorrect password") /* INCORRECT_PASSWORD */,
+ LPGENW("Too many login attempts") /* TOO_MANY_LOGIN_ATTEMPTS */,
+ LPGENW("PASSWORD_HAS_CHANGED") /* PASSWORD_HAS_CHANGED */,
+ LPGENW("PERIODIC_UIC_UPDATE_FAILED") /* PERIODIC_UIC_UPDATE_FAILED */,
+ LPGENW("DB_DISK_FULL") /* DB_DISK_FULL */,
+ LPGENW("DB_IO_ERROR") /* DB_IO_ERROR */,
+ LPGENW("DB_CORRUPT") /* DB_CORRUPT */,
+ LPGENW("DB_FAILURE") /* DB_FAILURE */,
+ LPGENW("INVALID_APP_ID") /* INVALID_APP_ID */,
+ LPGENW("APP_ID_FAILURE") /* APP_ID_FAILURE */,
+ LPGENW("UNSUPPORTED_VERSION") /* UNSUPPORTED_VERSION */,
+ LPGENW("ATO (Account TakeOver) detected, account blocked") /* ATO_BLOCKED */,
+ LPGENW("Logout from another instance") /* REMOTE_LOGOUT */,
+ LPGENW("") /* ACCESS_TOKEN_RENEWAL_FAILED */
+};
+
+wchar_t *CSkypeProto::PasswordChangeReasons[] =
+{
+ LPGENW("Password change succeeded") /* PWD_OK */,
+ LPGENW("") /* PWD_CHANGING */,
+ LPGENW("Old password was incorrect") /* PWD_INVALID_OLD_PASSWORD */,
+ LPGENW("Failed to verify password. No connection to server") /* PWD_SERVER_CONNECT_FAILED */,
+ LPGENW("Password was set but server didn't like it much") /* PWD_OK_BUT_CHANGE_SUGGESTED */,
+ LPGENW("New password was exactly the same as old one") /* PWD_MUST_DIFFER_FROM_OLD */,
+ LPGENW("The new password was unacceptable") /* PWD_INVALID_NEW_PWD */,
+ LPGENW("Account was currently not logged in") /* PWD_MUST_LOG_IN_TO_CHANGE */,
+};
bool CSkypeProto::IsOnline()
{
return this->m_iStatus > ID_STATUS_OFFLINE;
}
-void __cdecl CSkypeProto::SignInAsync(void*)
-{
- if ( !this->rememberPassword)
- {
- ::mir_free(this->password);
- this->password = NULL;
- }
- else
- {
- ::CallService(MS_DB_CRYPT_ENCODESTRING, ::strlen(this->password), (LPARAM)this->password);
- }
-
- this->LoadOwnInfo(this);
- this->LoadContactList(this);
- this->LoadAuthWaitList(this);
- this->LoadChatList(this);
-
- this->SetStatus(this->m_iDesiredStatus);
-
- fetch(this->transferList);
-}
-
bool CSkypeProto::PrepareLogin()
{
this->login = ::db_get_wsa(NULL, this->m_szModuleName, SKYPE_SETTINGS_LOGIN);
@@ -155,9 +101,9 @@ bool CSkypeProto::PreparePassword()
return true;
}
-bool CSkypeProto::SignIn(int status)
+bool CSkypeProto::LogIn()
{
- if ( !this->PrepareLogin())
+ if (this->IsOnline()|| !this->PrepareLogin())
return false;
if (g_skype->GetAccount(::mir_u2a(this->login), this->account))
@@ -180,6 +126,18 @@ bool CSkypeProto::SignIn(int status)
return true;
}
+void CSkypeProto::LogOut()
+{
+ if (this->IsOnline() || this->m_iStatus == ID_STATUS_CONNECTING)
+ {
+ this->account->SetAvailability(CContact::OFFLINE);
+ this->account->Logout(true);
+
+ this->m_iStatus = ID_STATUS_OFFLINE;
+ this->SetAllContactStatus(ID_STATUS_OFFLINE);
+ }
+}
+
void CSkypeProto::SetAccountSettings()
{
int port = this->GetSettingWord("Port", rand() % 10000 + 10000);
@@ -195,23 +153,180 @@ void CSkypeProto::SetAccountSettings()
}
}
-bool CSkypeProto::IsAvatarChanged(const SEBinary &avatar)
+void CSkypeProto::InitProxy()
+{
+ if (this->hNetLibUser)
+ {
+ NETLIBUSERSETTINGS nlus = { sizeof(NETLIBUSERSETTINGS) };
+ ::CallService(MS_NETLIB_GETUSERSETTINGS, (WPARAM)this->hNetLibUser, (LPARAM)&nlus);
+
+ if (nlus.useProxy)
+ {
+ char address[MAX_PATH];
+ ::mir_snprintf(address, MAX_PATH, "%s:%d", nlus.szProxyServer, nlus.wProxyPort);
+
+ switch (nlus.proxyType)
+ {
+ case PROXYTYPE_HTTP:
+ case PROXYTYPE_HTTPS:
+ g_skype->SetInt(SETUPKEY_HTTPS_PROXY_ENABLE, 1);
+ g_skype->SetInt(SETUPKEY_SOCKS_PROXY_ENABLE, 0);
+ g_skype->SetStr(SETUPKEY_HTTPS_PROXY_ADDR, address);
+ if (nlus.useProxyAuth)
+ {
+ char encodedPass[MAX_PATH];
+ Base64::Encode(nlus.szProxyAuthPassword, encodedPass, MAX_PATH);
+
+ g_skype->SetStr(SETUPKEY_HTTPS_PROXY_USER, nlus.szProxyAuthUser);
+ g_skype->SetStr(SETUPKEY_HTTPS_PROXY_PWD, encodedPass);
+ }
+ break;
+
+ case PROXYTYPE_SOCKS4:
+ case PROXYTYPE_SOCKS5:
+ g_skype->SetInt(SETUPKEY_HTTPS_PROXY_ENABLE, 0);
+ g_skype->SetInt(SETUPKEY_SOCKS_PROXY_ENABLE, 1);
+ g_skype->SetStr(SETUPKEY_SOCKS_PROXY_ADDR, address);
+ if (nlus.useProxyAuth)
+ {
+ g_skype->SetStr(SETUPKEY_SOCKS_PROXY_USER, nlus.szProxyAuthUser);
+ g_skype->SetStr(SETUPKEY_SOCKS_PROXY_PWD, nlus.szProxyAuthPassword);
+ }
+ break;
+
+ default:
+ g_skype->Delete(SETUPKEY_HTTPS_PROXY_ENABLE);
+ g_skype->Delete(SETUPKEY_HTTPS_PROXY_ADDR);
+ g_skype->Delete(SETUPKEY_HTTPS_PROXY_USER);
+ g_skype->Delete(SETUPKEY_HTTPS_PROXY_PWD);
+ g_skype->Delete(SETUPKEY_SOCKS_PROXY_ENABLE);
+ g_skype->Delete(SETUPKEY_SOCKS_PROXY_ADDR);
+ g_skype->Delete(SETUPKEY_SOCKS_PROXY_USER);
+ g_skype->Delete(SETUPKEY_SOCKS_PROXY_PWD);
+ break;
+ }
+ }
+ }
+}
+
+void CSkypeProto::OnLoggedIn()
{
- bool result = false;
+ if ( !this->rememberPassword)
+ {
+ ::mir_free(this->password);
+ this->password = NULL;
+ }
+ else
+ {
+ ::CallService(MS_DB_CRYPT_ENCODESTRING, ::strlen(this->password), (LPARAM)this->password);
+ }
+
+ this->LoadOwnInfo(this);
+ this->LoadChatList(this);
+ this->LoadContactList(this);
+ this->LoadAuthWaitList(this);
+
- ::mir_md5_byte_t digest[16];
- ::mir_md5_hash((PBYTE)avatar.data(), (int)avatar.size(), digest);
+ fetch(this->transferList);
- DBVARIANT dbv;
- ::db_get(NULL, this->m_szModuleName, "AvatarHash", &dbv);
- if (dbv.type == DBVT_BLOB && dbv.pbVal && dbv.cpbVal == 16)
+ this->SetStatus(this->m_iDesiredStatus);
+}
+
+void CSkypeProto::OnCblUpdated()
+{
+ // reload our CL after skype CL fully synced
+ this->LoadContactList(this);
+ this->LoadAuthWaitList(this);
+}
+
+void CSkypeProto::OnLoggedOut(CAccount::LOGOUTREASON reason)
+{
+ this->m_iStatus = ID_STATUS_OFFLINE;
+ this->SendBroadcast(
+ ACKTYPE_LOGIN, ACKRESULT_FAILED,
+ NULL, this->SkypeToMirandaLoginError(reason));
+
+ this->ShowNotification(CSkypeProto::LogoutReasons[reason - 1]);
+
+ if (this->rememberPassword && reason == CAccount::INCORRECT_PASSWORD)
{
- if (::memcmp(digest, dbv.pbVal, 16) == 0)
+ this->rememberPassword = false;
+ if (this->password)
{
- result = true;
+ ::mir_free(this->password);
+ this->password = NULL;
}
}
- ::db_free(&dbv);
+}
+
+void CSkypeProto::OnAccountChanged(int prop)
+{
+ switch(prop)
+ {
+ case CAccount::P_STATUS:
+ CAccount::STATUS loginStatus;
+ this->account->GetPropStatus(loginStatus);
+
+ if (loginStatus == CAccount::LOGGED_IN)
+ {
+ //this->ForkThread(&CSkypeProto::SignInAsync, 0);
+ this->OnLoggedIn();
+ }
- return result;
+ if (loginStatus == CAccount::LOGGED_OUT)
+ {
+ CAccount::LOGOUTREASON reason;
+ if (!this->account->GetPropLogoutreason(reason))
+ break;
+
+ if (reason != CAccount::LOGOUT_CALLED)
+ {
+ this->OnLoggedOut(reason);
+ }
+ }
+ break;
+
+ case CAccount::P_CBLSYNCSTATUS:
+ {
+ CAccount::CBLSYNCSTATUS status;
+ this->account->GetPropCblsyncstatus(status);
+ if (status == CAccount::CBL_IN_SYNC)
+ {
+ this->OnCblUpdated();
+ }
+ }
+ break;
+
+ case CAccount::P_PWDCHANGESTATUS:
+ {
+ CAccount::PWDCHANGESTATUS status;
+ this->account->GetPropPwdchangestatus(status);
+ if (status != CAccount::PWD_CHANGING)
+ this->ShowNotification(CSkypeProto::PasswordChangeReasons[status]);
+ }
+ break;
+
+ //case CAccount::P_AVATAR_IMAGE:
+ case CAccount::P_AVATAR_TIMESTAMP:
+ this->UpdateProfileAvatar(this->account.fetch());
+ break;
+
+ //case CAccount::P_MOOD_TEXT:
+ case CAccount::P_MOOD_TIMESTAMP:
+ this->UpdateProfileStatusMessage(this->account.fetch());
+ break;
+
+ case CAccount::P_PROFILE_TIMESTAMP:
+ this->UpdateProfile(this->account.fetch());
+ break;
+
+ /*case CAccount::P_AVAILABILITY:
+ {
+ CContact::AVAILABILITY status;
+ this->account->GetPropAvailability(status);
+ if (status != CContact::CONNECTING && status >= CContact::ONLINE)
+ this->SetStatus(this->SkypeToMirandaStatus(status));
+ }
+ break;*/
+ }
} \ No newline at end of file
diff --git a/protocols/Skype/src/skype_avatars.cpp b/protocols/Skype/src/skype_avatars.cpp
new file mode 100644
index 0000000000..afb2dac02f
--- /dev/null
+++ b/protocols/Skype/src/skype_avatars.cpp
@@ -0,0 +1,218 @@
+#include "skype_proto.h"
+
+bool CSkypeProto::IsAvatarChanged(const SEBinary &avatar)
+{
+ bool result = false;
+
+ ::mir_md5_byte_t digest[16];
+ ::mir_md5_hash((PBYTE)avatar.data(), (int)avatar.size(), digest);
+
+ DBVARIANT dbv;
+ ::db_get(NULL, this->m_szModuleName, "AvatarHash", &dbv);
+ if (dbv.type == DBVT_BLOB && dbv.pbVal && dbv.cpbVal == 16)
+ {
+ if (::memcmp(digest, dbv.pbVal, 16) == 0)
+ {
+ result = true;
+ }
+ }
+ ::db_free(&dbv);
+
+ return result;
+}
+
+int CSkypeProto::DetectAvatarFormatBuffer(const char *pBuffer)
+{
+ if (!strncmp(pBuffer, "%PNG", 4))
+ return PA_FORMAT_PNG;
+
+ if (!strncmp(pBuffer, "GIF8", 4))
+ return PA_FORMAT_GIF;
+
+ if (!_strnicmp(pBuffer, "<?xml", 5))
+ return PA_FORMAT_XML;
+
+ if ((((DWORD*)pBuffer)[0] == 0xE0FFD8FFul) || (((DWORD*)pBuffer)[0] == 0xE1FFD8FFul))
+ return PA_FORMAT_JPEG;
+
+ if (!strncmp(pBuffer, "BM", 2))
+ return PA_FORMAT_BMP;
+
+ return PA_FORMAT_UNKNOWN;
+}
+
+int CSkypeProto::DetectAvatarFormat(const wchar_t *path)
+{
+ int src = _wopen(path, _O_BINARY | _O_RDONLY, 0);
+ if (src == -1)
+ return PA_FORMAT_UNKNOWN;
+
+ char pBuf[32];
+ _read(src, pBuf, 32);
+ _close(src);
+
+ return CSkypeProto::DetectAvatarFormatBuffer(pBuf);
+}
+
+wchar_t* CSkypeProto::GetContactAvatarFilePath(HANDLE hContact)
+{
+ wchar_t* path = new wchar_t[MAX_PATH];
+
+ this->InitCustomFolders();
+
+ if (m_hAvatarsFolder == NULL || FoldersGetCustomPathT(m_hAvatarsFolder, path, MAX_PATH, _T("")))
+ {
+ wchar_t *tmpPath = ::Utils_ReplaceVarsT(L"%miranda_avatarcache%");
+ ::mir_sntprintf(path, MAX_PATH, _T("%s\\%S"), tmpPath, this->m_szModuleName);
+ ::mir_free(tmpPath);
+ }
+
+ DWORD dwAttributes = GetFileAttributes(path);
+ if (dwAttributes == 0xffffffff || (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
+ CallService(MS_UTILS_CREATEDIRTREET, 0, (LPARAM)path);
+
+ ::mir_ptr<wchar_t> sid(::db_get_wsa(hContact, this->m_szModuleName, SKYPE_SETTINGS_LOGIN));
+ if (hContact != NULL)
+ ::mir_sntprintf(path, MAX_PATH, _T("%s\\%s.jpg"), path, sid);
+ else if (sid != NULL)
+ ::mir_sntprintf(path, MAX_PATH, _T("%s\\%s avatar.jpg"), path, sid);
+ else
+ {
+ delete [] path;
+ return NULL;
+ }
+
+ return path;
+}
+
+INT_PTR __cdecl CSkypeProto::GetAvatarInfo(WPARAM, LPARAM lParam)
+{
+ PROTO_AVATAR_INFORMATIONW *pai = (PROTO_AVATAR_INFORMATIONW*)lParam;
+
+ if (this->GetSettingWord(pai->hContact, "AvatarTS"))
+ {
+ return GAIR_NOAVATAR;
+ }
+
+ wchar_t *sid = ::db_get_wsa(pai->hContact, this->m_szModuleName, SKYPE_SETTINGS_LOGIN);
+ if (sid)
+ {
+ wchar_t *path = this->GetContactAvatarFilePath(pai->hContact);
+ if (path && !_waccess(path, 0))
+ {
+ ::wcsncpy(pai->filename, path, SIZEOF(pai->filename));
+ pai->format = PA_FORMAT_JPEG;
+ return GAIR_SUCCESS;
+ }
+
+ ::mir_free(sid);
+ }
+
+ return GAIR_NOAVATAR;
+}
+
+INT_PTR __cdecl CSkypeProto::GetAvatarCaps(WPARAM wParam, LPARAM lParam)
+{
+ switch (wParam)
+ {
+ case AF_MAXSIZE:
+ {
+ POINT *size = (POINT*)lParam;
+ if (size)
+ {
+ size->x = 96;
+ size->y = 96;
+ }
+ }
+ break;
+
+ case AF_PROPORTION:
+ return PIP_NONE;
+
+ case AF_FORMATSUPPORTED:
+ return lParam == PA_FORMAT_JPEG;
+
+ case AF_ENABLED:
+ return 1;
+
+ case AF_DONTNEEDDELAYS:
+ return 1;
+
+ case AF_MAXFILESIZE:
+ // server accepts images of 32000 bytees, not bigger
+ return 32000;
+
+ case AF_DELAYAFTERFAIL:
+ // do not request avatar again if server gave an error
+ return 1;// * 60 * 60 * 1000; // one hour
+
+ case AF_FETCHALWAYS:
+ // avatars can be fetched all the time (server only operation)
+ return 1;
+ }
+
+ return 0;
+}
+
+INT_PTR __cdecl CSkypeProto::GetMyAvatar(WPARAM wParam, LPARAM lParam)
+{
+ if (!wParam) return -2;
+
+ wchar_t *path = this->GetContactAvatarFilePath(NULL);
+ if (path && ::PathFileExists(path))
+ {
+ ::wcsncpy((wchar_t *)wParam, path, (int)lParam);
+ delete path;
+ return 0;
+ }
+
+ return -1;
+}
+
+INT_PTR __cdecl CSkypeProto::SetMyAvatar(WPARAM, LPARAM lParam)
+{
+ wchar_t *path = (wchar_t *)lParam;
+ int iRet = -1;
+
+ if (path)
+ {
+ wchar_t *avatarPath = this->GetContactAvatarFilePath(NULL);
+ if (::wcscmp(path, avatarPath) && !::CopyFile(path, avatarPath, FALSE))
+ {
+ this->Log(L"Failed to copy our avatar to local storage.");
+ return iRet;
+ }
+
+ SEBinary avatar = this->GetAvatarBinary(avatarPath);
+ if (avatar.size() == 0)
+ {
+ this->Log(L"Failed to read avatar file.");
+ return iRet;
+ }
+
+ if (!this->IsAvatarChanged(avatar))
+ {
+ this->Log(L"New avatar are same with old.");
+ return iRet;
+ }
+
+ Skype::VALIDATERESULT result = Skype::NOT_VALIDATED;
+ if (!this->account->SetAvatar(avatar, result))
+ {
+ this->Log(CSkypeProto::ValidationReasons[result]);
+ return iRet;
+ }
+
+ uint newTS = this->account->GetUintProp(/* *::P_AVATAR_TIMESTAMP */ 182);
+ this->SetSettingDword("AvatarTS", newTS);
+ iRet = 0;
+ }
+ else
+ {
+ this->account->SetBinProperty(Account::P_AVATAR_IMAGE, SEBinary());
+ this->DeleteSetting("AvatarTS");
+ iRet = 0;
+ }
+
+ return iRet;
+} \ No newline at end of file
diff --git a/protocols/Skype/src/skype_chat.cpp b/protocols/Skype/src/skype_chat.cpp
index 51c00fe2dc..a63d3475fa 100644
--- a/protocols/Skype/src/skype_chat.cpp
+++ b/protocols/Skype/src/skype_chat.cpp
@@ -3,7 +3,7 @@
#include <m_message.h>
#include <m_history.h>
-wchar_t *CSkypeProto::Groups[] =
+wchar_t *CSkypeProto::Roles[] =
{
L"Creator",
L"Admin",
@@ -189,9 +189,9 @@ void CSkypeProto::CreateChatWindow(CConversation::Ref conversation, bool showWin
gce.cbSize = sizeof(GCEVENT);
gce.dwFlags = GC_TCHAR;
gce.pDest = &gcd;
- for (int i = 0; i < SIZEOF(CSkypeProto::Groups); i++)
+ for (int i = 0; i < SIZEOF(CSkypeProto::Roles); i++)
{
- gce.ptszStatus =:: TranslateW(CSkypeProto::Groups[i]);
+ gce.ptszStatus =:: TranslateW(CSkypeProto::Roles[i]);
::CallServiceSync(MS_GC_EVENT, NULL, (LPARAM)&gce);
}
@@ -256,9 +256,9 @@ wchar_t *CSkypeProto::StartChat(const wchar_t *cid, const SEStringList &invitedC
gce.cbSize = sizeof(GCEVENT);
gce.dwFlags = GC_TCHAR;
gce.pDest = &gcd;
- for (int i = 0; i < SIZEOF(CSkypeProto::Groups); i++)
+ for (int i = 0; i < SIZEOF(CSkypeProto::Roles); i++)
{
- gce.ptszStatus =:: TranslateW(CSkypeProto::Groups[i]);
+ gce.ptszStatus =:: TranslateW(CSkypeProto::Roles[i]);
::CallServiceSync(MS_GC_EVENT, NULL, (LPARAM)&gce);
}
@@ -298,7 +298,6 @@ void CSkypeProto::JoinToChat(CConversation::Ref conversation, bool showWindow)
CParticipant::RANK rank;
participants[i]->GetPropRank(rank);
- mir_ptr<wchar_t> group = ::mir_utf8decodeW(CParticipant::GetRankName(rank));
CContact::Ref contact;
g_skype->GetContact((char *)mir_ptr<char>(::mir_utf8encodeW(sid)), contact);
@@ -309,7 +308,7 @@ void CSkypeProto::JoinToChat(CConversation::Ref conversation, bool showWindow)
this->AddChatContact(
chatID,
sid,
- group,
+ CSkypeProto::Roles[rank],
this->SkypeToMirandaStatus(status));
}
@@ -368,7 +367,7 @@ void CSkypeProto::SendChatMessage(const wchar_t *cid, const wchar_t *sid, const
void CSkypeProto::AddChatContact(const wchar_t *cid, const wchar_t *sid, const wchar_t *group, const WORD status)
{
this->RaiseChatEvent(cid, sid, GC_EVENT_JOIN);
- this->RaiseChatEvent(cid, sid, GC_EVENT_ADDSTATUS, 0, 0, CSkypeProto::Groups[SKYPE_CHAT_GROUP_WIRTER], L"Owner");
+ this->RaiseChatEvent(cid, sid, GC_EVENT_ADDSTATUS, 0, 0, CSkypeProto::Roles[SKYPE_CHAT_GROUP_WIRTER], L"Owner");
this->RaiseChatEvent(cid, sid, GC_EVENT_SETCONTACTSTATUS, status);
}
diff --git a/protocols/Skype/src/skype_dialogs.cpp b/protocols/Skype/src/skype_dialogs.cpp
index cf8f640541..adb3405f6b 100644
--- a/protocols/Skype/src/skype_dialogs.cpp
+++ b/protocols/Skype/src/skype_dialogs.cpp
@@ -687,7 +687,7 @@ INT_PTR CALLBACK CSkypeProto::InviteToChatProc(HWND hwndDlg, UINT msg, WPARAM wP
param->ppro->AddChatContact(
chatID,
::mir_utf8decodeW(invitedContacts[i]),
- mir_utf8decodeW(CParticipant::GetRankName(CParticipant::SPEAKER)),
+ CSkypeProto::Roles[CParticipant::SPEAKER],
status);
}
@@ -710,7 +710,7 @@ INT_PTR CALLBACK CSkypeProto::InviteToChatProc(HWND hwndDlg, UINT msg, WPARAM wP
param->ppro->AddChatContact(
chatID,
::mir_utf8decodeW(invitedContacts[i]),
- ::mir_utf8decodeW(CParticipant::GetRankName(CParticipant::SPEAKER)),
+ CSkypeProto::Roles[CParticipant::SPEAKER],
status);
}
}
diff --git a/protocols/Skype/src/skype_events.cpp b/protocols/Skype/src/skype_events.cpp
index d88d6016e2..56fc74a695 100644
--- a/protocols/Skype/src/skype_events.cpp
+++ b/protocols/Skype/src/skype_events.cpp
@@ -5,9 +5,7 @@ int CSkypeProto::OnModulesLoaded(WPARAM, LPARAM)
this->InitChat();
this->InitNetLib();
this->InitCustomFolders();
-
- this->HookEvent(ME_OPT_INITIALISE, &CSkypeProto::OnOptionsInit);
- this->HookEvent(ME_USERINFO_INITIALISE, &CSkypeProto::OnUserInfoInit);
+ this->InitInstanceHookList();
g_skype->SetOnMessageCallback(
(CSkype::OnMessaged)&CSkypeProto::OnMessage,
@@ -20,6 +18,7 @@ int CSkypeProto::OnPreShutdown(WPARAM, LPARAM)
{
this->SetStatus(ID_STATUS_OFFLINE);
+ this->UninitInstanceHookList();
this->UninitNetLib();
return 0;
@@ -52,17 +51,13 @@ int CSkypeProto::OnMessagePreCreate(WPARAM, LPARAM lParam)
MessageWindowEvent *evt = (MessageWindowEvent *)lParam;
MessageRef message(evt->seq);
-
SEBinary guid;
if (message->GetPropGuid(guid))
{
- evt->dbei->pBlob = (PBYTE)::mir_realloc(evt->dbei->pBlob, (evt->dbei->cbBlob + 33));
- ::memcpy(&evt->dbei->pBlob[evt->dbei->cbBlob], guid.data(), 32);
- evt->dbei->cbBlob += 33;
+ evt->dbei->pBlob = (PBYTE)::mir_realloc(evt->dbei->pBlob, guid.size() + 1);
+ ::strncpy((char *)&evt->dbei->pBlob[evt->dbei->cbBlob], guid.data(), guid.size());
}
- //delete message;
-
return 1;
}
@@ -387,7 +382,7 @@ void CSkypeProto::OnMessage(CConversation::Ref conversation, CMessage::Ref messa
this->AddChatContact(
cid,
sid,
- ::mir_utf8decodeW(CParticipant::GetRankName(CParticipant::WRITER)),
+ CSkypeProto::Roles[CParticipant::WRITER],
status);
}
}
diff --git a/protocols/Skype/src/skype_hooks.cpp b/protocols/Skype/src/skype_hooks.cpp
new file mode 100644
index 0000000000..9fb927f1a2
--- /dev/null
+++ b/protocols/Skype/src/skype_hooks.cpp
@@ -0,0 +1,31 @@
+#include "skype_proto.h"
+
+LIST<void> CSkypeProto::hookList(1);
+
+void CSkypeProto::InitHookList()
+{
+ CSkypeProto::hookList.insert(
+ ::HookEvent(ME_CLIST_PREBUILDCONTACTMENU, &CSkypeProto::PrebuildContactMenu));
+}
+
+void CSkypeProto::UninitHookList()
+{
+ for (int i = 0; i < CSkypeProto::hookList.getCount(); i++)
+ {
+ ::UnhookEvent(CSkypeProto::hookList[i]);
+ }
+}
+
+void CSkypeProto::InitInstanceHookList()
+{
+ this->HookEvent(ME_OPT_INITIALISE, &CSkypeProto::OnOptionsInit);
+ this->HookEvent(ME_USERINFO_INITIALISE, &CSkypeProto::OnUserInfoInit);
+}
+
+void CSkypeProto::UninitInstanceHookList()
+{
+ for (int i = 0; i < this->instanceHookList.getCount(); i++)
+ {
+ ::UnhookEvent(this->instanceHookList[i]);
+ }
+} \ No newline at end of file
diff --git a/protocols/Skype/src/skype_instances.cpp b/protocols/Skype/src/skype_instances.cpp
index 996c588164..138d241e77 100644
--- a/protocols/Skype/src/skype_instances.cpp
+++ b/protocols/Skype/src/skype_instances.cpp
@@ -2,6 +2,11 @@
LIST<CSkypeProto> CSkypeProto::instanceList(1, CSkypeProto::CompareProtos);
+int CSkypeProto::CompareProtos(const CSkypeProto *p1, const CSkypeProto *p2)
+{
+ return wcscmp(p1->m_tszUserName, p2->m_tszUserName);
+}
+
CSkypeProto* CSkypeProto::InitSkypeProto(const char* protoName, const wchar_t* userName)
{
if (CSkypeProto::instanceList.getCount() > 0)
diff --git a/protocols/Skype/src/skype_menus.cpp b/protocols/Skype/src/skype_menus.cpp
index fc08f4b814..9fcff09721 100644
--- a/protocols/Skype/src/skype_menus.cpp
+++ b/protocols/Skype/src/skype_menus.cpp
@@ -130,10 +130,6 @@ int CSkypeProto::PrebuildContactMenu(WPARAM wParam, LPARAM lParam)
void CSkypeProto::InitMenus()
{
- CSkypeProto::hPrebuildMenuHook = ::HookEvent(
- ME_CLIST_PREBUILDCONTACTMENU,
- CSkypeProto::PrebuildContactMenu);
-
TMenuParam mnu = {0};
mnu.cbSize = sizeof(mnu);
mnu.name = "SkypeAccountChooser";
@@ -174,7 +170,7 @@ void CSkypeProto::InitMenus()
void CSkypeProto::UninitMenus()
{
- ::UnhookEvent(CSkypeProto::hPrebuildMenuHook);
+ //::UnhookEvent(CSkypeProto::hPrebuildMenuHook);
}
void CSkypeProto::OnInitStatusMenu()
diff --git a/protocols/Skype/src/skype_netlib.cpp b/protocols/Skype/src/skype_netlib.cpp
index e0782e4a9f..0095383ffe 100644
--- a/protocols/Skype/src/skype_netlib.cpp
+++ b/protocols/Skype/src/skype_netlib.cpp
@@ -1,5 +1,4 @@
#include "skype_proto.h"
-#include "base64/base64.h"
void CSkypeProto::InitNetLib()
{
@@ -22,62 +21,6 @@ void CSkypeProto::UninitNetLib()
this->hNetLibUser = NULL;
}
-void CSkypeProto::InitProxy()
-{
- if (this->hNetLibUser)
- {
- NETLIBUSERSETTINGS nlus = { sizeof(NETLIBUSERSETTINGS) };
- ::CallService(MS_NETLIB_GETUSERSETTINGS, (WPARAM)this->hNetLibUser, (LPARAM)&nlus);
-
- if (nlus.useProxy)
- {
- char address[MAX_PATH];
- ::mir_snprintf(address, MAX_PATH, "%s:%d", nlus.szProxyServer, nlus.wProxyPort);
-
- switch (nlus.proxyType)
- {
- case PROXYTYPE_HTTP:
- case PROXYTYPE_HTTPS:
- g_skype->SetInt(SETUPKEY_HTTPS_PROXY_ENABLE, 1);
- g_skype->SetInt(SETUPKEY_SOCKS_PROXY_ENABLE, 0);
- g_skype->SetStr(SETUPKEY_HTTPS_PROXY_ADDR, address);
- if (nlus.useProxyAuth)
- {
- char encodedPass[MAX_PATH];
- Base64::Encode(nlus.szProxyAuthPassword, encodedPass, MAX_PATH);
-
- g_skype->SetStr(SETUPKEY_HTTPS_PROXY_USER, nlus.szProxyAuthUser);
- g_skype->SetStr(SETUPKEY_HTTPS_PROXY_PWD, encodedPass);
- }
- break;
-
- case PROXYTYPE_SOCKS4:
- case PROXYTYPE_SOCKS5:
- g_skype->SetInt(SETUPKEY_HTTPS_PROXY_ENABLE, 0);
- g_skype->SetInt(SETUPKEY_SOCKS_PROXY_ENABLE, 1);
- g_skype->SetStr(SETUPKEY_SOCKS_PROXY_ADDR, address);
- if (nlus.useProxyAuth)
- {
- g_skype->SetStr(SETUPKEY_SOCKS_PROXY_USER, nlus.szProxyAuthUser);
- g_skype->SetStr(SETUPKEY_SOCKS_PROXY_PWD, nlus.szProxyAuthPassword);
- }
- break;
-
- default:
- g_skype->Delete(SETUPKEY_HTTPS_PROXY_ENABLE);
- g_skype->Delete(SETUPKEY_HTTPS_PROXY_ADDR);
- g_skype->Delete(SETUPKEY_HTTPS_PROXY_USER);
- g_skype->Delete(SETUPKEY_HTTPS_PROXY_PWD);
- g_skype->Delete(SETUPKEY_SOCKS_PROXY_ENABLE);
- g_skype->Delete(SETUPKEY_SOCKS_PROXY_ADDR);
- g_skype->Delete(SETUPKEY_SOCKS_PROXY_USER);
- g_skype->Delete(SETUPKEY_SOCKS_PROXY_PWD);
- break;
- }
- }
- }
-}
-
void CSkypeProto::Log(const wchar_t *fmt, ...)
{
va_list va;
diff --git a/protocols/Skype/src/skype_proto.cpp b/protocols/Skype/src/skype_proto.cpp
index e3b4edefd2..49ca34ba61 100644
--- a/protocols/Skype/src/skype_proto.cpp
+++ b/protocols/Skype/src/skype_proto.cpp
@@ -1,37 +1,28 @@
#include "skype_proto.h"
-CSkypeProto::CSkypeProto(const char* protoName, const TCHAR* userName)
+CSkypeProto::CSkypeProto(const char* protoName, const TCHAR* userName) :
+ instanceHookList(1),
+ instanceServiceList(1)
{
::ProtoConstructor(this, protoName, userName);
this->rememberPassword = false;
- this->signin_lock = CreateMutex(0, false, 0);
this->SetAllContactStatus(ID_STATUS_OFFLINE);
DBEVENTTYPEDESCR dbEventType = { sizeof(dbEventType) };
dbEventType.module = m_szModuleName;
dbEventType.eventType = SKYPE_DB_EVENT_TYPE_CALL;
- dbEventType.descr = "Call";
+ dbEventType.descr = "Skype call";
::CallService(MS_DB_EVENT_REGISTERTYPE, 0, (LPARAM)&dbEventType);
- //this->HookEvent(ME_MSG_PRECREATEEVENT, &CSkypeProto::OnMessagePreCreate);
-
- this->CreateServiceObj(PS_CREATEACCMGRUI, &CSkypeProto::OnAccountManagerInit);
- // Chat API
- this->CreateServiceObj(PS_JOINCHAT, &CSkypeProto::OnJoinChat);
- this->CreateServiceObj(PS_LEAVECHAT, &CSkypeProto::OnLeaveChat);
- // Avatar API
- this->CreateServiceObj(PS_GETAVATARINFOT, &CSkypeProto::GetAvatarInfo);
- this->CreateServiceObj(PS_GETAVATARCAPS, &CSkypeProto::GetAvatarCaps);
- this->CreateServiceObj(PS_GETMYAVATART, &CSkypeProto::GetMyAvatar);
- this->CreateServiceObj(PS_SETMYAVATART, &CSkypeProto::SetMyAvatar);
+ this->HookEvent(ME_MSG_PRECREATEEVENT, &CSkypeProto::OnMessagePreCreate);
+
+ this->InitInstanceServiceList();
}
CSkypeProto::~CSkypeProto()
{
- ::CloseHandle(this->signin_lock);
-
::mir_free(this->login);
if (this->password)
{
@@ -39,6 +30,8 @@ CSkypeProto::~CSkypeProto()
this->password = NULL;
}
+ this->UninitInstanceServiceList();
+
::ProtoDestructor(this);
}
@@ -367,7 +360,7 @@ int __cdecl CSkypeProto::SetApparentMode( HANDLE hContact, int mode ) { retur
int CSkypeProto::SetStatus(int new_status)
{
- switch (new_status)
+ /*switch (new_status)
{
case ID_STATUS_OCCUPIED:
new_status = ID_STATUS_DND;
@@ -380,7 +373,7 @@ int CSkypeProto::SetStatus(int new_status)
case ID_STATUS_NA:
new_status = ID_STATUS_AWAY;
break;
- }
+ }*/
if (new_status == this->m_iStatus)
return 0;
@@ -388,27 +381,23 @@ int CSkypeProto::SetStatus(int new_status)
int old_status = this->m_iStatus;
this->m_iDesiredStatus = new_status;
- switch (new_status)
+ if (new_status == ID_STATUS_OFFLINE)
+ {
+ this->LogOut();
+ }
+ else
{
- case ID_STATUS_OFFLINE:
- if (this->IsOnline() || this->m_iStatus == ID_STATUS_CONNECTING)
- {
- this->account->SetAvailability(CContact::OFFLINE);
- this->account->Logout(true);
-
- this->m_iStatus = new_status;
- this->SetAllContactStatus(ID_STATUS_OFFLINE);
- }
- break;
-
- default:
if (old_status == ID_STATUS_OFFLINE && !this->IsOnline())
{
this->m_iStatus = ID_STATUS_CONNECTING;
- if ( !this->SignIn(this->m_iDesiredStatus)) return 0;
+ if ( !this->LogIn())
+ return 0;
}
else
{
+ if (this->m_iStatus == ID_STATUS_CONNECTING)
+ return 0;
+
CContact::AVAILABILITY availability = this->MirandaToSkypeStatus(new_status);
if (availability != CContact::UNKNOWN)
{
@@ -416,7 +405,6 @@ int CSkypeProto::SetStatus(int new_status)
this->m_iStatus = new_status;
}
}
- break;
}
this->SetSettingWord("Status", this->m_iStatus);
diff --git a/protocols/Skype/src/skype_proto.h b/protocols/Skype/src/skype_proto.h
index 313b231465..c57c4f0858 100644
--- a/protocols/Skype/src/skype_proto.h
+++ b/protocols/Skype/src/skype_proto.h
@@ -221,9 +221,6 @@ public:
static CSkypeProto* InitSkypeProto(const char* protoName, const wchar_t* userName);
static int UninitSkypeProto(CSkypeProto* ppro);
- // services
- static void InitServiceList();
-
// icons
static void InitIcons();
static void UninitIcons();
@@ -234,6 +231,14 @@ public:
static void InitMenus();
static void UninitMenus();
+ // services
+ static void InitServiceList();
+ static void UninitServiceList();
+
+ // hooks
+ static void InitHookList();
+ static void UninitHookList();
+
INT_PTR __cdecl InviteCommand(WPARAM, LPARAM);
static CSkypeProto* GetInstanceByHContact(HANDLE hContact);
@@ -249,32 +254,43 @@ protected:
CContactGroup::Ref authWaitList;
// account
- void OnAccountChanged(int prop);
+ static wchar_t* LogoutReasons[];
+ static wchar_t* PasswordChangeReasons[];
wchar_t *login;
char *password;
- bool rememberPassword;
-
+ bool rememberPassword;
+
bool RequestPassword(PasswordRequestBoxParam &param);
bool ChangePassword(PasswordChangeBoxParam &param);
bool PrepareLogin();
bool PreparePassword();
- HANDLE signin_lock;
- bool SignIn(int status);
- void __cdecl SignInAsync(void*);
+ void InitProxy();
+ void SetAccountSettings();
+
+ bool LogIn();
+ void LogOut();
+
+ void OnLoggedIn();
+ void OnCblUpdated();
+ void OnLoggedOut(CAccount::LOGOUTREASON reason);
- void SetAccountSettings();
+ void OnAccountChanged(int prop);
+ // avatars
bool IsAvatarChanged(const SEBinary &avatar);
- static SettingItem setting[19];
+ static int DetectAvatarFormatBuffer(const char *pBuffer);
+ static int DetectAvatarFormat(const wchar_t *path);
- static wchar_t* LogoutReasons[];
- static wchar_t* ValidationReasons[];
- static wchar_t* PasswordChangeReasons[];
- static LanguagesListEntry languages[223];
+ wchar_t* GetContactAvatarFilePath(HANDLE hContact);
+
+ INT_PTR __cdecl GetAvatarInfo(WPARAM, LPARAM);
+ INT_PTR __cdecl GetAvatarCaps(WPARAM, LPARAM);
+ INT_PTR __cdecl GetMyAvatar(WPARAM, LPARAM);
+ INT_PTR __cdecl SetMyAvatar(WPARAM, LPARAM);
// messages
void OnMessage(CConversation::Ref conversation, CMessage::Ref message);
@@ -286,7 +302,7 @@ protected:
void OnTransferChanged(CTransfer::Ref transfer, int prop);
// chat
- static wchar_t* Groups[];
+ static wchar_t* Roles[];
bool IsChatRoom(HANDLE hContact);
HANDLE GetChatRoomByCid(const wchar_t *cid);
@@ -350,6 +366,8 @@ protected:
void __cdecl SearchByEmailAsync(void*);
// profile
+ static SettingItem setting[19];
+
void UpdateProfileAvatar(SEObject *obj, HANDLE hContact = NULL);
void UpdateProfileAboutText(SEObject *obj, HANDLE hContact = NULL);
void UpdateProfileBirthday(SEObject *obj, HANDLE hContact = NULL);
@@ -372,17 +390,14 @@ protected:
void __cdecl LoadOwnInfo(void*);
// utils
+ static wchar_t* ValidationReasons[];
+
static void FakeAsync(void*);
void InitCustomFolders();
HANDLE m_hAvatarsFolder;
bool m_bInitDone;
- static int DetectAvatarFormatBuffer(const char *pBuffer);
- static int DetectAvatarFormat(const wchar_t *path);
-
- wchar_t* GetContactAvatarFilePath(HANDLE hContact);
-
int SkypeToMirandaLoginError(CAccount::LOGOUTREASON logoutReason);
static void ShowNotification(const wchar_t *message, int flags = 0, HANDLE hContact = NULL);
@@ -414,18 +429,25 @@ protected:
// netlib
HANDLE hNetLibUser;
+
void InitNetLib();
void UninitNetLib();
- void InitProxy();
+
void Log(const wchar_t *fmt, ...);
// services
static LIST<void> serviceList;
- INT_PTR __cdecl GetAvatarInfo(WPARAM, LPARAM);
- INT_PTR __cdecl GetAvatarCaps(WPARAM, LPARAM);
- INT_PTR __cdecl GetMyAvatar(WPARAM, LPARAM);
- INT_PTR __cdecl SetMyAvatar(WPARAM, LPARAM);
+ LIST<void> instanceServiceList;
+ void InitInstanceServiceList();
+ void UninitInstanceServiceList();
+
+ // hooks
+ static LIST<void> hookList;
+
+ LIST<void> instanceHookList;
+ void InitInstanceHookList();
+ void UninitInstanceHookList();
// icons
static _tag_iconList IconList[];
diff --git a/protocols/Skype/src/skype_services.cpp b/protocols/Skype/src/skype_services.cpp
index a7703a0e6d..4900b51b99 100644
--- a/protocols/Skype/src/skype_services.cpp
+++ b/protocols/Skype/src/skype_services.cpp
@@ -1,6 +1,6 @@
#include "skype_proto.h"
-LIST<void> CSkypeProto::serviceList(0);
+LIST<void> CSkypeProto::serviceList(1);
void CSkypeProto::InitServiceList()
{
@@ -8,134 +8,32 @@ void CSkypeProto::InitServiceList()
::CreateServiceFunction("Skype/MenuChoose", CSkypeProto::MenuChooseService));
}
-INT_PTR __cdecl CSkypeProto::GetAvatarInfo(WPARAM, LPARAM lParam)
+void CSkypeProto::UninitServiceList()
{
- PROTO_AVATAR_INFORMATIONW *pai = (PROTO_AVATAR_INFORMATIONW*)lParam;
-
- if (this->GetSettingWord(pai->hContact, "AvatarTS"))
- {
- return GAIR_NOAVATAR;
- }
-
- wchar_t *sid = ::db_get_wsa(pai->hContact, this->m_szModuleName, SKYPE_SETTINGS_LOGIN);
- if (sid)
- {
- wchar_t *path = this->GetContactAvatarFilePath(pai->hContact);
- if (path && !_waccess(path, 0))
- {
- ::wcsncpy(pai->filename, path, SIZEOF(pai->filename));
- pai->format = PA_FORMAT_JPEG;
- return GAIR_SUCCESS;
- }
-
- ::mir_free(sid);
- }
-
- return GAIR_NOAVATAR;
-}
-
-INT_PTR __cdecl CSkypeProto::GetAvatarCaps(WPARAM wParam, LPARAM lParam)
-{
- switch (wParam)
+ for (int i = 0; i < CSkypeProto::serviceList.getCount(); i++)
{
- case AF_MAXSIZE:
- {
- POINT *size = (POINT*)lParam;
- if (size)
- {
- size->x = 96;
- size->y = 96;
- }
- }
- break;
-
- case AF_PROPORTION:
- return PIP_NONE;
-
- case AF_FORMATSUPPORTED:
- return lParam == PA_FORMAT_JPEG;
-
- case AF_ENABLED:
- return 1;
-
- case AF_DONTNEEDDELAYS:
- return 1;
-
- case AF_MAXFILESIZE:
- // server accepts images of 32000 bytees, not bigger
- return 32000;
-
- case AF_DELAYAFTERFAIL:
- // do not request avatar again if server gave an error
- return 1;// * 60 * 60 * 1000; // one hour
-
- case AF_FETCHALWAYS:
- // avatars can be fetched all the time (server only operation)
- return 1;
+ ::DestroyServiceFunction(CSkypeProto::serviceList[i]);
}
-
- return 0;
}
-INT_PTR __cdecl CSkypeProto::GetMyAvatar(WPARAM wParam, LPARAM lParam)
+void CSkypeProto::InitInstanceServiceList()
{
- if (!wParam) return -2;
-
- wchar_t *path = this->GetContactAvatarFilePath(NULL);
- if (path && ::PathFileExists(path))
- {
- ::wcsncpy((wchar_t *)wParam, path, (int)lParam);
- delete path;
- return 0;
- }
-
- return -1;
+ // Message API
+ this->CreateServiceObj(PS_CREATEACCMGRUI, &CSkypeProto::OnAccountManagerInit);
+ // Chat API
+ this->CreateServiceObj(PS_JOINCHAT, &CSkypeProto::OnJoinChat);
+ this->CreateServiceObj(PS_LEAVECHAT, &CSkypeProto::OnLeaveChat);
+ // Avatar API
+ this->CreateServiceObj(PS_GETAVATARINFOT, &CSkypeProto::GetAvatarInfo);
+ this->CreateServiceObj(PS_GETAVATARCAPS, &CSkypeProto::GetAvatarCaps);
+ this->CreateServiceObj(PS_GETMYAVATART, &CSkypeProto::GetMyAvatar);
+ this->CreateServiceObj(PS_SETMYAVATART, &CSkypeProto::SetMyAvatar);
}
-INT_PTR __cdecl CSkypeProto::SetMyAvatar(WPARAM, LPARAM lParam)
+void CSkypeProto::UninitInstanceServiceList()
{
- wchar_t *path = (wchar_t *)lParam;
- int iRet = -1;
-
- if (path)
+ for (int i = 0; i < this->instanceServiceList.getCount(); i++)
{
- wchar_t *avatarPath = this->GetContactAvatarFilePath(NULL);
- if (::wcscmp(path, avatarPath) && !::CopyFile(path, avatarPath, FALSE))
- {
- this->Log(L"Failed to copy our avatar to local storage.");
- return iRet;
- }
-
- SEBinary avatar = this->GetAvatarBinary(avatarPath);
- if (avatar.size() == 0)
- {
- this->Log(L"Failed to read avatar file.");
- return iRet;
- }
-
- if (!this->IsAvatarChanged(avatar))
- {
- this->Log(L"New avatar are same with old.");
- return iRet;
- }
-
- Skype::VALIDATERESULT result = Skype::NOT_VALIDATED;
- if (!this->account->SetAvatar(avatar, result))
- {
- this->Log(CSkypeProto::ValidationReasons[result]);
- return iRet;
- }
-
- uint newTS = this->account->GetUintProp(/* *::P_AVATAR_TIMESTAMP */ 182);
- this->SetSettingDword("AvatarTS", newTS);
- iRet = 0;
+ ::DestroyServiceFunction(this->instanceServiceList[i]);
}
- else
- {
- this->account->SetBinProperty(Account::P_AVATAR_IMAGE, SEBinary());
- this->DeleteSetting("AvatarTS");
- iRet = 0;
- }
-
- return iRet;
} \ No newline at end of file
diff --git a/protocols/Skype/src/skype_utils.cpp b/protocols/Skype/src/skype_utils.cpp
index 199e3b3c8f..55cbcb6149 100644
--- a/protocols/Skype/src/skype_utils.cpp
+++ b/protocols/Skype/src/skype_utils.cpp
@@ -1,37 +1,6 @@
#include "skype_proto.h"
-wchar_t* CSkypeProto::LogoutReasons[] =
-{
- LPGENW("LOGOUT_CALLED") /* LOGOUT_CALLED */,
- LPGENW("HTTPS_PROXY_AUTH_FAILED") /* HTTPS_PROXY_AUTH_FAILED */,
- LPGENW("SOCKS_PROXY_AUTH_FAILED") /* SOCKS_PROXY_AUTH_FAILED */,
- LPGENW("P2P_CONNECT_FAILED") /* P2P_CONNECT_FAILED */,
- LPGENW("SERVER_CONNECT_FAILED") /* SERVER_CONNECT_FAILED */,
- LPGENW("SERVER_OVERLOADED") /* SERVER_OVERLOADED */,
- LPGENW("DB_IN_USE") /* DB_IN_USE */,
- LPGENW("Invalid skypename") /* INVALID_SKYPENAME */,
- LPGENW("Invalid email") /* INVALID_EMAIL */,
- LPGENW("Unacceptable password") /* UNACCEPTABLE_PASSWORD */,
- LPGENW("SKYPENAME_TAKEN") /* SKYPENAME_TAKEN */,
- LPGENW("REJECTED_AS_UNDERAGE") /* REJECTED_AS_UNDERAGE */,
- LPGENW("NO_SUCH_IDENTITY") /* NO_SUCH_IDENTITY */,
- LPGENW("Incorrect password") /* INCORRECT_PASSWORD */,
- LPGENW("Too many login attempts") /* TOO_MANY_LOGIN_ATTEMPTS */,
- LPGENW("PASSWORD_HAS_CHANGED") /* PASSWORD_HAS_CHANGED */,
- LPGENW("PERIODIC_UIC_UPDATE_FAILED") /* PERIODIC_UIC_UPDATE_FAILED */,
- LPGENW("DB_DISK_FULL") /* DB_DISK_FULL */,
- LPGENW("DB_IO_ERROR") /* DB_IO_ERROR */,
- LPGENW("DB_CORRUPT") /* DB_CORRUPT */,
- LPGENW("DB_FAILURE") /* DB_FAILURE */,
- LPGENW("INVALID_APP_ID") /* INVALID_APP_ID */,
- LPGENW("APP_ID_FAILURE") /* APP_ID_FAILURE */,
- LPGENW("UNSUPPORTED_VERSION") /* UNSUPPORTED_VERSION */,
- LPGENW("ATO (Account TakeOver) detected, account blocked") /* ATO_BLOCKED */,
- LPGENW("Logout from another instance") /* REMOTE_LOGOUT */,
- LPGENW("") /* ACCESS_TOKEN_RENEWAL_FAILED */
-};
-
-wchar_t* CSkypeProto::ValidationReasons[] =
+wchar_t *CSkypeProto::ValidationReasons[] =
{
LPGENW("NOT_VALIDATED") /* NOT_VALIDATED */,
LPGENW("Validation succeeded") /* VALIDATED_OK */,
@@ -46,273 +15,7 @@ wchar_t* CSkypeProto::ValidationReasons[] =
LPGENW("Value starts with an invalid character") /* STARTS_WITH_INVALID_CHAR */,
};
-wchar_t* CSkypeProto::PasswordChangeReasons[] =
-{
- LPGENW("Password change succeeded") /* PWD_OK */,
- LPGENW("") /* PWD_CHANGING */,
- LPGENW("Old password was incorrect") /* PWD_INVALID_OLD_PASSWORD */,
- LPGENW("Failed to verify password. No connection to server") /* PWD_SERVER_CONNECT_FAILED */,
- LPGENW("Password was set but server didn't like it much") /* PWD_OK_BUT_CHANGE_SUGGESTED */,
- LPGENW("New password was exactly the same as old one") /* PWD_MUST_DIFFER_FROM_OLD */,
- LPGENW("The new password was unacceptable") /* PWD_INVALID_NEW_PWD */,
- LPGENW("Account was currently not logged in") /* PWD_MUST_LOG_IN_TO_CHANGE */,
-};
-
-LanguagesListEntry CSkypeProto::languages[] =
-{
- {"Abkhazian", "ab"},
- {"Afar", "aa"},
- {"Afrikaans", "af"},
- {"Akan", "ak"},
- {"Albanian", "sq"},
- {"Amharic", "am"},
- {"Arabic", "ar"},
- {"Aragonese", "an"},
- {"Armenian", "hy"},
- {"Assamese", "as"},
- {"Avaric", "av"},
- {"Avestan", "ae"},
- {"Aymara", "ay"},
- {"Azerbaijani", "az"},
- {"Bambara", "bm"},
- {"Bashkir", "ba"},
- {"Basque", "eu"},
- {"Belarusian", "be"},
- {"Bengali", "bn"},
- {"Bihari languages", "bh"},
- {"Bislama", "bi"},
- {"Bokmal, Norwegian", "nb"},
- {"Bosnian", "bs"},
- {"Breton", "br"},
- {"Bulgarian", "bg"},
- {"Burmese", "my"},
- {"Castilian", "es"},
- {"Catalan", "ca"},
- {"Central Khmer", "km"},
- {"Chamorro", "ch"},
- {"Chechen", "ce"},
- {"Chewa", "ny"},
- {"Chichewa", "ny"},
- {"Chinese", "zh"},
- {"Chuang", "za"},
- {"Church Slavic", "cu"},
- {"Church Slavonic", "cu"},
- {"Chuvash", "cv"},
- {"Cornish", "kw"},
- {"Corsican", "co"},
- {"Cree", "cr"},
- {"Croatian", "hr"},
- {"Czech", "cs"},
- {"Danish", "da"},
- {"Dhivehi", "dv"},
- {"Divehi", "dv"},
- {"Dutch", "nl"},
- {"Dzongkha", "dz"},
- {"English", "en"},
- {"Esperanto", "eo"},
- {"Estonian", "et"},
- {"Ewe", "ee"},
- {"Faroese", "fo"},
- {"Fijian", "fj"},
- {"Finnish", "fi"},
- {"Flemish", "nl"},
- {"French", "fr"},
- {"Fulah", "ff"},
- {"Gaelic", "gd"},
- {"Galician", "gl"},
- {"Ganda", "lg"},
- {"Georgian", "ka"},
- {"German", "de"},
- {"Gikuyu", "ki"},
- {"Greek, Modern (1453-)", "el"},
- {"Greenlandic", "kl"},
- {"Guarani", "gn"},
- {"Gujarati", "gu"},
- {"Haitian", "ht"},
- {"Haitian Creole", "ht"},
- {"Hausa", "ha"},
- {"Hebrew", "he"},
- {"Herero", "hz"},
- {"Hindi", "hi"},
- {"Hiri Motu", "ho"},
- {"Hungarian", "hu"},
- {"Icelandic", "is"},
- {"Ido", "io"},
- {"Igbo", "ig"},
- {"Indonesian", "id"},
- {"Interlingua (International Auxiliary Language Association)", "ia"},
- {"Interlingue", "ie"},
- {"Inuktitut", "iu"},
- {"Inupiaq", "ik"},
- {"Irish", "ga"},
- {"Italian", "it"},
- {"Japanese", "ja"},
- {"Javanese", "jv"},
- {"Kalaallisut", "kl"},
- {"Kannada", "kn"},
- {"Kanuri", "kr"},
- {"Kashmiri", "ks"},
- {"Kazakh", "kk"},
- {"Kikuyu", "ki"},
- {"Kinyarwanda", "rw"},
- {"Kirghiz", "ky"},
- {"Komi", "kv"},
- {"Kongo", "kg"},
- {"Korean", "ko"},
- {"Kuanyama", "kj"},
- {"Kurdish", "ku"},
- {"Kwanyama", "kj"},
- {"Kyrgyz", "ky"},
- {"Lao", "lo"},
- {"Latin", "la"},
- {"Latvian", "lv"},
- {"Letzeburgesch", "lb"},
- {"Limburgan", "li"},
- {"Limburger", "li"},
- {"Limburgish", "li"},
- {"Lingala", "ln"},
- {"Lithuanian", "lt"},
- {"Luba-Katanga", "lu"},
- {"Luxembourgish", "lb"},
- {"Macedonian", "mk"},
- {"Malagasy", "mg"},
- {"Malay", "ms"},
- {"Malayalam", "ml"},
- {"Maldivian", "dv"},
- {"Maltese", "mt"},
- {"Manx", "gv"},
- {"Maori", "mi"},
- {"Marathi", "mr"},
- {"Marshallese", "mh"},
- {"Moldavian", "ro"},
- {"Moldovan", "ro"},
- {"Mongolian", "mn"},
- {"Nauru", "na"},
- {"Navaho", "nv"},
- {"Navajo", "nv"},
- {"Ndebele, North", "nd"},
- {"Ndebele, South", "nr"},
- {"Ndonga", "ng"},
- {"Nepali", "ne"},
- {"North Ndebele", "nd"},
- {"Northern Sami", "se"},
- {"Norwegian", "no"},
- {"Norwegian Bokmal", "nb"},
- {"Norwegian Nynorsk", "nn"},
- {"Nuosu", "ii"},
- {"Nyanja", "ny"},
- {"Nynorsk, Norwegian", "nn"},
- {"Occidental", "ie"},
- {"Occitan (post 1500)", "oc"},
- {"Ojibwa", "oj"},
- {"Old Bulgarian", "cu"},
- {"Old Church Slavonic", "cu"},
- {"Old Slavonic", "cu"},
- {"Oriya", "or"},
- {"Oromo", "om"},
- {"Ossetian", "os"},
- {"Ossetic", "os"},
- {"Pali", "pi"},
- {"Panjabi", "pa"},
- {"Pashto", "ps"},
- {"Persian", "fa"},
- {"Polish", "pl"},
- {"Portuguese", "pt"},
- {"Punjabi", "pa"},
- {"Pushto", "ps"},
- {"Quechua", "qu"},
- {"Romanian", "ro"},
- {"Romansh", "rm"},
- {"Rundi", "rn"},
- {"Russian", "ru"},
- {"Samoan", "sm"},
- {"Sango", "sg"},
- {"Sanskrit", "sa"},
- {"Sardinian", "sc"},
- {"Scottish Gaelic", "gd"},
- {"Serbian", "sr"},
- {"Shona", "sn"},
- {"Sichuan Yi", "ii"},
- {"Sindhi", "sd"},
- {"Sinhala", "si"},
- {"Sinhalese", "si"},
- {"Slovak", "sk"},
- {"Slovenian", "sl"},
- {"Somali", "so"},
- {"Sotho, Southern", "st"},
- {"South Ndebele", "nr"},
- {"Spanish", "es"},
- {"Sundanese", "su"},
- {"Swahili", "sw"},
- {"Swati", "ss"},
- {"Swedish", "sv"},
- {"Tagalog", "tl"},
- {"Tahitian", "ty"},
- {"Tajik", "tg"},
- {"Tamil", "ta"},
- {"Tatar", "tt"},
- {"Telugu", "te"},
- {"Thai", "th"},
- {"Tibetan", "bo"},
- {"Tigrinya", "ti"},
- {"Tonga (Tonga Islands)", "to"},
- {"Tsonga", "ts"},
- {"Tswana", "tn"},
- {"Turkish", "tr"},
- {"Turkmen", "tk"},
- {"Twi", "tw"},
- {"Uighur", "ug"},
- {"Ukrainian", "uk"},
- {"Urdu", "ur"},
- {"Uyghur", "ug"},
- {"Uzbek", "uz"},
- {"Valencian", "ca"},
- {"Venda", "ve"},
- {"Vietnamese", "vi"},
- {"Volapuk", "vo"},
- {"Walloon", "wa"},
- {"Welsh", "cy"},
- {"Western Frisian", "fy"},
- {"Wolof", "wo"},
- {"Xhosa", "xh"},
- {"Yiddish", "yi"},
- {"Yoruba", "yo"},
- {"Zhuang", "za"},
- {"Zulu", "zu"}
-};
-
-int CSkypeProto::DetectAvatarFormatBuffer(const char *pBuffer)
-{
- if (!strncmp(pBuffer, "%PNG", 4))
- return PA_FORMAT_PNG;
-
- if (!strncmp(pBuffer, "GIF8", 4))
- return PA_FORMAT_GIF;
-
- if (!_strnicmp(pBuffer, "<?xml", 5))
- return PA_FORMAT_XML;
-
- if ((((DWORD*)pBuffer)[0] == 0xE0FFD8FFul) || (((DWORD*)pBuffer)[0] == 0xE1FFD8FFul))
- return PA_FORMAT_JPEG;
-
- if (!strncmp(pBuffer, "BM", 2))
- return PA_FORMAT_BMP;
-
- return PA_FORMAT_UNKNOWN;
-}
-
-int CSkypeProto::DetectAvatarFormat(const wchar_t *path)
-{
- int src = _wopen(path, _O_BINARY | _O_RDONLY, 0);
- if (src == -1)
- return PA_FORMAT_UNKNOWN;
-
- char pBuf[32];
- _read(src, pBuf, 32);
- _close(src);
-
- return CSkypeProto::DetectAvatarFormatBuffer(pBuf);
-}
+// ---
void CSkypeProto::InitCustomFolders()
{
@@ -322,45 +25,11 @@ void CSkypeProto::InitCustomFolders()
m_bInitDone = true;
TCHAR AvatarsFolder[MAX_PATH];
- mir_sntprintf(AvatarsFolder, SIZEOF(AvatarsFolder), _T("%%miranda_avatarcache%%\\%S"), this->m_szModuleName);
+ ::mir_sntprintf(AvatarsFolder, SIZEOF(AvatarsFolder), _T("%%miranda_avatarcache%%\\%S"), this->m_szModuleName);
m_hAvatarsFolder = ::FoldersRegisterCustomPathT(LPGEN("Avatars"), m_szModuleName, AvatarsFolder, m_tszUserName);
}
-wchar_t* CSkypeProto::GetContactAvatarFilePath(HANDLE hContact)
-{
- wchar_t* path = new wchar_t[MAX_PATH];
-
- this->InitCustomFolders();
-
- if (m_hAvatarsFolder == NULL || FoldersGetCustomPathT(m_hAvatarsFolder, path, MAX_PATH, _T("")))
- {
- wchar_t *tmpPath = ::Utils_ReplaceVarsT(L"%miranda_avatarcache%");
- ::mir_sntprintf(path, MAX_PATH, _T("%s\\%S"), tmpPath, this->m_szModuleName);
- ::mir_free(tmpPath);
- }
-
- DWORD dwAttributes = GetFileAttributes(path);
- if (dwAttributes == 0xffffffff || (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
- CallService(MS_UTILS_CREATEDIRTREET, 0, (LPARAM)path);
-
- ::mir_ptr<wchar_t> sid(::db_get_wsa(hContact, this->m_szModuleName, SKYPE_SETTINGS_LOGIN));
- if (hContact != NULL)
- ::mir_sntprintf(path, MAX_PATH, _T("%s\\%s.jpg"), path, sid);
- else if (sid != NULL)
- ::mir_sntprintf(path, MAX_PATH, _T("%s\\%s avatar.jpg"), path, sid);
- else
- {
- delete [] path;
- return NULL;
- }
-
- return path;
-}
-
-int CSkypeProto::CompareProtos(const CSkypeProto *p1, const CSkypeProto *p2)
-{
- return wcscmp(p1->m_tszUserName, p2->m_tszUserName);
-}
+// ---
void CSkypeProto::CreateServiceObj(const char* szService, SkypeServiceFunc serviceProc)
{
diff --git a/protocols/Skype/src/skypekit/conversation.cpp b/protocols/Skype/src/skypekit/conversation.cpp
index e907c82d75..c0d855150b 100644
--- a/protocols/Skype/src/skypekit/conversation.cpp
+++ b/protocols/Skype/src/skypekit/conversation.cpp
@@ -1,3 +1,11 @@
#include "conversation.h"
-CConversation::CConversation(unsigned int oid, SERootObject* root) : Conversation(oid, root) { }
+CConversation::CConversation(unsigned int oid, SERootObject* root) : Conversation(oid, root)
+{
+}
+
+void CConversation::OnParticipantListChange()
+{
+ this->GetParticipants(this->participants, CConversation::OTHER_CONSUMERS);
+ fetch(this->participants);
+}
diff --git a/protocols/Skype/src/skypekit/conversation.h b/protocols/Skype/src/skypekit/conversation.h
index 9fdc064962..26e7fb990b 100644
--- a/protocols/Skype/src/skypekit/conversation.h
+++ b/protocols/Skype/src/skypekit/conversation.h
@@ -1,6 +1,7 @@
#pragma once
#include "common.h"
+#include "participant.h"
class CConversation : public Conversation
{
@@ -12,4 +13,7 @@ public:
private:
CSkypeProto* proto;
+ CParticipant::Refs participants;
+
+ void OnParticipantListChange();
}; \ No newline at end of file
diff --git a/protocols/Skype/src/skypekit/participant.cpp b/protocols/Skype/src/skypekit/participant.cpp
index 8b25254a0e..035003d1c9 100644
--- a/protocols/Skype/src/skypekit/participant.cpp
+++ b/protocols/Skype/src/skypekit/participant.cpp
@@ -2,32 +2,7 @@
CParticipant::CParticipant(unsigned int oid, SERootObject* root) : Participant(oid, root) { }
-SEString CParticipant::GetRankName(CParticipant::RANK rank)
+void CParticipant::OnChange(int prop)
{
- char *result = NULL;
- switch (rank)
- {
- case CParticipant::CREATOR:
- result = "Creator";
- break;
- case CParticipant::ADMIN:
- result = "Admin";
- break;
- case CParticipant::SPEAKER:
- result = "Speaker";
- break;
- case CParticipant::WRITER:
- result = "Writer";
- break;
- case CParticipant::SPECTATOR:
- result = "Spectator";
- break;
- case CParticipant::RETIRED:
- result = "Retried";
- break;
- case CParticipant::OUTLAW:
- result = "Outlaw";
- break;
- }
- return result;
+ int i = 0;
} \ No newline at end of file
diff --git a/protocols/Skype/src/skypekit/participant.h b/protocols/Skype/src/skypekit/participant.h
index 3a09d28017..3d6e38b445 100644
--- a/protocols/Skype/src/skypekit/participant.h
+++ b/protocols/Skype/src/skypekit/participant.h
@@ -10,5 +10,6 @@ public:
CParticipant(unsigned int oid, SERootObject* root);
- static SEString GetRankName(CParticipant::RANK rank);
+private:
+ void OnChange(int prop);
}; \ No newline at end of file