summaryrefslogtreecommitdiff
path: root/protocols
diff options
context:
space:
mode:
Diffstat (limited to 'protocols')
-rw-r--r--protocols/Skype/Skype_10.vcxproj8
-rw-r--r--protocols/Skype/Skype_10.vcxproj.filters8
-rw-r--r--protocols/Skype/res/Resource.rc6
-rw-r--r--protocols/Skype/src/resource.h7
-rw-r--r--protocols/Skype/src/skype.cpp14
-rw-r--r--protocols/Skype/src/skype_chat.cpp248
-rw-r--r--protocols/Skype/src/skype_contacts.cpp45
-rw-r--r--protocols/Skype/src/skype_dialogs.cpp70
-rw-r--r--protocols/Skype/src/skype_events.cpp145
-rw-r--r--protocols/Skype/src/skype_proto.cpp29
-rw-r--r--protocols/Skype/src/skype_proto.h86
-rw-r--r--protocols/Skype/src/skype_subclassing.cpp17
-rw-r--r--protocols/Skype/src/skype_subclassing.h6
-rw-r--r--protocols/Skype/src/skype_utils.cpp51
14 files changed, 617 insertions, 123 deletions
diff --git a/protocols/Skype/Skype_10.vcxproj b/protocols/Skype/Skype_10.vcxproj
index a0f6e6cccb..a55b1cd7cb 100644
--- a/protocols/Skype/Skype_10.vcxproj
+++ b/protocols/Skype/Skype_10.vcxproj
@@ -210,6 +210,14 @@
<ResourceCompile Include="res\Version.rc" />
<ResourceCompile Include="res\Resource.rc" />
</ItemGroup>
+ <ItemGroup>
+ <None Include="..\..\..\SkypeKit\keypair.bin" />
+ <None Include="..\..\..\SkypeKit\SDK\bin\windows-x86\windows-x86-skypekit.exe" />
+ <None Include="res\auth_grant.ico" />
+ <None Include="res\auth_request.ico" />
+ <None Include="res\auth_revoke.ico" />
+ <None Include="res\Main.ico" />
+ </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
diff --git a/protocols/Skype/Skype_10.vcxproj.filters b/protocols/Skype/Skype_10.vcxproj.filters
index 6f7f8ae872..4d031f4ed2 100644
--- a/protocols/Skype/Skype_10.vcxproj.filters
+++ b/protocols/Skype/Skype_10.vcxproj.filters
@@ -92,4 +92,12 @@
<Filter>Resource Filess</Filter>
</ResourceCompile>
</ItemGroup>
+ <ItemGroup>
+ <None Include="res\Main.ico" />
+ <None Include="res\auth_grant.ico" />
+ <None Include="res\auth_request.ico" />
+ <None Include="res\auth_revoke.ico" />
+ <None Include="..\..\..\SkypeKit\SDK\bin\windows-x86\windows-x86-skypekit.exe" />
+ <None Include="..\..\..\SkypeKit\keypair.bin" />
+ </ItemGroup>
</Project> \ No newline at end of file
diff --git a/protocols/Skype/res/Resource.rc b/protocols/Skype/res/Resource.rc
index 04acddc71b..485f51fe0f 100644
--- a/protocols/Skype/res/Resource.rc
+++ b/protocols/Skype/res/Resource.rc
@@ -189,6 +189,12 @@ BEGIN
EDITTEXT IDC_SL,84,17,123,13,ES_AUTOHSCROLL
LTEXT "Password:",IDC_STATIC,17,35,61,8
EDITTEXT IDC_PW,84,33,123,13,ES_PASSWORD | ES_AUTOHSCROLL
+ GROUPBOX "Connection",IDC_STATIC,7,69,291,47
+ LTEXT "Use port",IDC_STATIC,17,81,44,8
+ EDITTEXT IDC_PORT,84,79,40,14,ES_AUTOHSCROLL
+ LTEXT "for incoming connections",IDC_STATIC,130,81,158,8
+ CONTROL "Use ports 80 and 443 as alternative incoming",IDC_USE_ALT_PORTS,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,97,271,10
END
diff --git a/protocols/Skype/src/resource.h b/protocols/Skype/src/resource.h
index 715b1b9b1c..12cd98774d 100644
--- a/protocols/Skype/src/resource.h
+++ b/protocols/Skype/src/resource.h
@@ -1,6 +1,6 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
-// Used by e:\Projects\C++\MirandaNG\protocols\Skype\res\Resource.rc
+// Used by D:\Projects\CPlusPlus\MirandaNG\protocols\Skype\res\Resource.rc
//
#define IDD_SKYPEACCOUNT 9
#define IDD_OPTIONS 10
@@ -32,6 +32,9 @@
#define IDC_SAVE 1013
#define IDC_LIST 1014
#define IDC_UPLOADING 1015
+#define IDC_PORT 1016
+#define IDC_CHECK1 1017
+#define IDC_USE_ALT_PORTS 1017
// Next default values for new objects
//
@@ -39,7 +42,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 108
#define _APS_NEXT_COMMAND_VALUE 40001
-#define _APS_NEXT_CONTROL_VALUE 1016
+#define _APS_NEXT_CONTROL_VALUE 1018
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
diff --git a/protocols/Skype/src/skype.cpp b/protocols/Skype/src/skype.cpp
index ad23c7c14e..f2b22adf17 100644
--- a/protocols/Skype/src/skype.cpp
+++ b/protocols/Skype/src/skype.cpp
@@ -124,7 +124,7 @@ unsigned char decode(char * data, unsigned char *buf, int len)
}
}
#undef BASE64DECODE_READ_NEXT_CHAR
-
+
unsigned char *decode(char * data, int *outlen)
{
if ( !data) { *outlen = 0; return (unsigned char*)""; }
@@ -142,15 +142,15 @@ char* LoadKeyPair()
if (hRes) {
HGLOBAL hResource = LoadResource(g_hInstance, hRes);
if (hResource) {
- aes_context ctx;
-
+ aes_context ctx;
+
int basedecodedkey = decodeSize((char*)MY_KEY);
unsigned char *tmpK = (unsigned char*)malloc(basedecodedkey + 1);
decode((char*)MY_KEY, tmpK, basedecodedkey);
tmpK[basedecodedkey] = 0;
-
-
- aes_set_key( &ctx, tmpK, 128);
+
+
+ aes_set_key( &ctx, tmpK, 128);
int dwResSize = SizeofResource(g_hInstance, hRes);
char *pData = (char*)GlobalLock(hResource);
char *pCopy = (char*)_alloca(dwResSize+1);
@@ -165,7 +165,7 @@ char* LoadKeyPair()
aes_decrypt(&ctx, tmpD+i, bufD+i);
}
mir_free(tmpD);
- bufD[basedecoded] = 0; //cert should be null terminated
+ bufD[basedecoded] = 0; //cert should be null terminated
return (char*)bufD;
}
return NULL;
diff --git a/protocols/Skype/src/skype_chat.cpp b/protocols/Skype/src/skype_chat.cpp
index 25cd462268..57a5a2faff 100644
--- a/protocols/Skype/src/skype_chat.cpp
+++ b/protocols/Skype/src/skype_chat.cpp
@@ -8,13 +8,61 @@ bool CSkypeProto::IsChatRoom(HANDLE hContact)
return ::DBGetContactSettingByte(hContact, this->m_szModuleName, "ChatRoom", 0) > 0;
}
-void CSkypeProto::ChatValidateContact(HANDLE hItem, HWND hwndList)
+HANDLE CSkypeProto::GetChatRoomByID(const char *cid)
+{
+ HANDLE hContact = ::db_find_first();
+ while (hContact)
+ {
+ if (this->IsProtoContact(hContact) && this->IsChatRoom(hContact))
+ {
+ char *chatID = ::DBGetString(hContact, this->m_szModuleName, "ChatRoomID");
+ if (chatID && ::strcmp(cid, chatID) == 0)
+ return hContact;
+ }
+
+ hContact = ::db_find_next(hContact);
+ }
+
+ return 0;
+}
+
+HANDLE CSkypeProto::AddChatRoomByID(const char* cid, const char* name, DWORD flags)
+{
+ HANDLE hContact = this->GetChatRoomByID(cid);
+ if ( !hContact)
+ {
+ hContact = (HANDLE)::CallService(MS_DB_CONTACT_ADD, 0, 0);
+ ::CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)this->m_szModuleName);
+
+ ::DBWriteContactSettingByte(hContact, this->m_szModuleName, "ChatRoom", 1);
+ ::DBWriteContactSettingString(hContact, this->m_szModuleName, "ChatRoomID", cid);
+ ::DBWriteContactSettingString(hContact, this->m_szModuleName, "Nick", name);
+ ::DBWriteContactSettingWord(hContact, this->m_szModuleName, "Status", ID_STATUS_OFFLINE);
+ ::DBWriteContactSettingWord(hContact, this->m_szModuleName, "ApparentMode", ID_STATUS_OFFLINE);
+
+ wchar_t *defaultGroup = ::DBGetStringW(NULL, "Chat", "AddToGroup");
+ if (defaultGroup)
+ {
+ ::DBWriteContactSettingWString(hContact, "CList", "Group", defaultGroup);
+ }
+ }
+
+ return hContact;
+}
+
+void CSkypeProto::ChatValidateContact(HANDLE hItem, HWND hwndList, const char *contacts)
{
if ( !this->IsProtoContact(hItem) || this->IsChatRoom(hItem))
- ::SendMessage(hwndList, CLM_DELETEITEM, (WPARAM)hItem, 0);
+ {
+ /*char *sid = ::DBGetString(hItem, this->m_szModuleName, "sid");
+ if (!sid)
+ ::SendMessage(hwndList, CLM_DELETEITEM, (WPARAM)hItem, 0);
+ else if(contacts && ::strstr(contacts, sid))*/
+ ::SendMessage(hwndList, CLM_DELETEITEM, (WPARAM)hItem, 0);
+ }
}
-void CSkypeProto::ChatPrepare(HANDLE hItem, HWND hwndList)
+void CSkypeProto::ChatPrepare(HANDLE hItem, HWND hwndList, const char *contacts)
{
if (hItem == NULL)
hItem = (HANDLE)::SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_ROOT, 0);
@@ -26,10 +74,10 @@ void CSkypeProto::ChatPrepare(HANDLE hItem, HWND hwndList)
if (IsHContactGroup(hItem))
{
HANDLE hItemT = (HANDLE)::SendMessage(hwndList, CLM_GETNEXTITEM, CLGN_CHILD, (LPARAM)hItem);
- if (hItemT) this->ChatPrepare(hItemT, hwndList);
+ if (hItemT) this->ChatPrepare(hItemT, hwndList, contacts);
}
else if (IsHContactContact(hItem))
- this->ChatValidateContact(hItem, hwndList);
+ this->ChatValidateContact(hItem, hwndList, contacts);
hItem = hItemN;
}
@@ -88,38 +136,31 @@ void CSkypeProto::InitChat()
this->HookEvent(ME_GC_BUILDMENU, &CSkypeProto::OnGCMenuHook);
}
-void CSkypeProto::StartChat(HANDLE hContact, SEStringList &chatTargets)
+char *CSkypeProto::StartChat(const char *cid)
{
char *chatID;
SEString data;
- CConversation::Ref conversation;
+ CConversation::Ref conversation;
- if (hContact)
+ if (cid)
{
- chatID = ::DBGetString(hContact, this->m_szModuleName, "ChatRoomID");
- g_skype->GetConversationByIdentity(chatID, conversation);
+ g_skype->GetConversationByIdentity(cid, conversation);
conversation->GetJoinBlob(data);
- char *blob = ::mir_strdup((const char *)data);
- g_skype->GetConversationByBlob(blob, conversation, false);
+ g_skype->GetConversationByBlob(data, conversation, false);
conversation->Join();
- CParticipant::Refs participants;
- conversation->GetParticipants(participants, CConversation::OTHER_CONSUMERS);
- for (uint i = 0; i < participants.size(); i++)
- {
- participants[i]->GetPropIdentity(data);
- chatTargets.append(data);
- }
+ chatID = ::mir_strdup(cid);
}
- else if ( !g_skype->GetConversationByParticipants(chatTargets, conversation))
+ else
{
g_skype->CreateConference(conversation);
- conversation->SetOption(CConversation::P_OPT_JOINING_ENABLED, true);
- conversation->AddConsumers(chatTargets);
+ conversation->SetOption(CConversation::P_OPT_JOINING_ENABLED, true);
+ conversation->SetOption(CConversation::P_OPT_ENTRY_LEVEL_RANK, CParticipant::WRITER);
+ conversation->SetOption(CConversation::P_OPT_DISCLOSE_HISTORY, 1);
conversation->GetPropIdentity(data);
- chatID = ::mir_strdup((const char *)data);
- }
+ char *chatID = ::mir_strdup(data);
+ }
conversation->GetPropDisplayname(data);
char *chatName = ::mir_utf8decodeA((const char *)data);
@@ -145,33 +186,94 @@ void CSkypeProto::StartChat(HANDLE hContact, SEStringList &chatTargets)
gce.pszStatus = ::Translate("Others");
::CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce);
- for (uint i = 0; i < chatTargets.size(); i++)
- {
- HANDLE hContact = this->GetContactBySid(chatTargets[i]);
- gcd.iType = GC_EVENT_JOIN;
- gce.pszNick = ::DBGetString(hContact, this->m_szModuleName, "Nick");
- gce.pszUID = chatTargets[i];
- ::CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce);
- }
-
gcd.iType = GC_EVENT_CONTROL;
::CallServiceSync(MS_GC_EVENT, SESSION_INITDONE, (LPARAM)&gce);
::CallServiceSync(MS_GC_EVENT, SESSION_ONLINE, (LPARAM)&gce);
::CallServiceSync(MS_GC_EVENT, WINDOW_VISIBLE, (LPARAM)&gce);
::mir_free(chatName);
+
+ return chatID;
+}
+
+void CSkypeProto::JoinToChat(const char *cid, bool showWindow)
+{
+ char *chatID = ::mir_strdup(cid);
+
+ SEString data;
+ CConversation::Ref conversation;
+
+ g_skype->GetConversationByIdentity(cid, conversation);
+ conversation->GetJoinBlob(data);
+ g_skype->GetConversationByBlob(data, conversation, false);
+ conversation->Join();
+
+ conversation->GetPropDisplayname(data);
+ char *chatName = ::mir_utf8decodeA((const char *)data);
+
+ GCSESSION gcw = {0};
+ gcw.cbSize = sizeof(gcw);
+ gcw.iType = GCW_CHATROOM;
+ gcw.pszModule = this->m_szModuleName;
+ gcw.pszName = chatName;
+ gcw.pszID = chatID;
+ ::CallServiceSync(MS_GC_NEWSESSION, 0, (LPARAM)&gcw);
+
+ GCDEST gcd = { m_szModuleName, { NULL }, GC_EVENT_ADDGROUP };
+ gcd.pszID = chatID;
+
+ GCEVENT gce = {0};
+ gce.cbSize = sizeof(GCEVENT);
+ gce.pDest = &gcd;
+ gce.pszStatus = ::Translate("Me");
+ ::CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce);
+
+ gcd.iType = GC_EVENT_ADDGROUP;
+ gce.pszStatus = ::Translate("Others");
+ ::CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce);
+
+ gcd.iType = GC_EVENT_CONTROL;
+ ::CallServiceSync(MS_GC_EVENT, showWindow ? SESSION_INITDONE : WINDOW_HIDDEN, (LPARAM)&gce);
+ ::CallServiceSync(MS_GC_EVENT, SESSION_ONLINE, (LPARAM)&gce);
+ //::CallServiceSync(MS_GC_EVENT, showWindow ? WINDOW_VISIBLE : WINDOW_HIDDEN, (LPARAM)&gce);
+
+ CParticipant::Refs participants;
+ conversation->GetParticipants(participants, CConversation::OTHER_CONSUMERS);
+ for (uint i = 0; i < participants.size(); i++)
+ {
+ participants[i]->GetPropIdentity(data);
+ this->AddChatContact(cid, ::mir_strdup(data));
+ }
+
+ ::mir_free(chatName);
+ ::mir_free(chatID);
+}
+
+void CSkypeProto::LeaveChat(const char *cid)
+{
+ char *chatID = ::mir_strdup(cid);
+
+ GCDEST gcd = { m_szModuleName, { NULL }, GC_EVENT_CONTROL };
+ gcd.pszID = chatID;
+
+ GCEVENT gce = {0};
+ gce.cbSize = sizeof(GCEVENT);
+ gce.pDest = &gcd;
+ ::CallServiceSync(MS_GC_EVENT, SESSION_OFFLINE, (LPARAM)&gce);
+ ::CallServiceSync(MS_GC_EVENT, SESSION_TERMINATE, (LPARAM)&gce);
+
::mir_free(chatID);
}
-void CSkypeProto::ChatEvent(const char *chatID, const char *sid, int evt, const char *msg)
+void CSkypeProto::RaiseChatEvent(const char *cid, const char *sid, int evt, const char *message)
{
- char *idt = ::mir_strdup(chatID);
+ char *idt = ::mir_strdup(cid);
char *snt = ::mir_strdup(sid);
HANDLE hContact = this->GetContactBySid(sid);
char *nick = hContact ? (char *)::CallService(MS_CLIST_GETCONTACTDISPLAYNAME, WPARAM(hContact), 0) : snt;
- GCDEST gcd = { m_szModuleName, { NULL }, evt };
+ GCDEST gcd = { this->m_szModuleName, { NULL }, evt };
gcd.pszID = idt;
GCEVENT gce = {0};
@@ -182,7 +284,7 @@ void CSkypeProto::ChatEvent(const char *chatID, const char *sid, int evt, const
gce.pszUID = snt;
gce.bIsMe = ::stricmp(sid, this->login) == 0;
gce.pszStatus = gce.bIsMe ? ::Translate("Me") : ::Translate("Others");
- gce.pszText = msg;
+ gce.pszText = message;
gce.time = time(NULL);
::CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce);
@@ -190,39 +292,49 @@ void CSkypeProto::ChatEvent(const char *chatID, const char *sid, int evt, const
::mir_free(idt);
}
-INT_PTR __cdecl CSkypeProto::OnJoinChat(WPARAM wParam, LPARAM)
+void CSkypeProto::SendChatMessage(const char *cid, const char *sid, const char *message)
{
- HANDLE hContact = (HANDLE)wParam;
- SEStringList list;
- this->StartChat(hContact, list);
+ this->RaiseChatEvent(cid, sid, GC_EVENT_MESSAGE, message);
+}
- return 0;
+void CSkypeProto::AddChatContact(const char *cid, const char *sid)
+{
+ this->RaiseChatEvent(cid, sid, GC_EVENT_JOIN);
}
-INT_PTR __cdecl CSkypeProto::OnLeaveChat(WPARAM wParam, LPARAM)
+void CSkypeProto::KickChatContact(const char *cid, const char *sid)
{
- HANDLE hContact = (HANDLE)wParam;
- char *chatID = ::DBGetString(hContact, this->m_szModuleName, "ChatID");
- this->ChatLeave(chatID);
+ this->RaiseChatEvent(cid, sid, GC_EVENT_KICK);
+}
- return 0;
+void CSkypeProto::RemoveChatContact(const char *cid, const char *sid)
+{
+ this->RaiseChatEvent(cid, sid, GC_EVENT_QUIT);
}
-void CSkypeProto::ChatLeave(const char *chatID)
+INT_PTR __cdecl CSkypeProto::OnJoinChat(WPARAM wParam, LPARAM)
{
- char *idt = ::mir_strdup(chatID);
+ HANDLE hContact = (HANDLE)wParam;
+ if (hContact)
+ {
+ this->JoinToChat(::DBGetString(hContact, this->m_szModuleName, "ChatRoomID"));
+ }
- GCDEST gcd = { m_szModuleName, { NULL }, GC_EVENT_CONTROL };
- gcd.pszID = idt;
+ return 0;
+}
- GCEVENT gce = {0};
- gce.cbSize = sizeof(GCEVENT);
- //gce.dwFlags = GCEF_REMOVECONTACT;
- gce.pDest = &gcd;
- ::CallServiceSync(MS_GC_EVENT, SESSION_OFFLINE, (LPARAM)&gce);
- ::CallServiceSync(MS_GC_EVENT, SESSION_TERMINATE, (LPARAM)&gce);
+INT_PTR __cdecl CSkypeProto::OnLeaveChat(WPARAM wParam, LPARAM)
+{
+ HANDLE hContact = (HANDLE)wParam;
+ if (hContact)
+ {
+ char *cid = ::DBGetString(hContact, this->m_szModuleName, "ChatRoomID");
+ this->LeaveChat(cid);
+
+ ::mir_free(cid);
+ }
- ::mir_free(idt);
+ return 0;
}
int __cdecl CSkypeProto::OnGCEventHook(WPARAM, LPARAM lParam)
@@ -289,7 +401,7 @@ int __cdecl CSkypeProto::OnGCEventHook(WPARAM, LPARAM lParam)
break;
case 20:
- this->ChatLeave(chatID);
+ this->LeaveChat(chatID);
break;
}
break;
@@ -306,7 +418,7 @@ int __cdecl CSkypeProto::OnGCEventHook(WPARAM, LPARAM lParam)
break;
case 110:
- this->ChatLeave(chatID);
+ this->LeaveChat(chatID);
break;
}
break;
@@ -365,4 +477,20 @@ int __cdecl CSkypeProto::OnGCMenuHook(WPARAM, LPARAM lParam)
}
return 0;
+}
+
+
+char *CSkypeProto::GetChatUsers(const char *cid)
+{
+ GC_INFO gci = {0};
+ gci.Flags = USERS;
+ gci.pszModule = this->m_szModuleName;
+ gci.pszID = ::mir_a2t(cid);
+ ::CallService(MS_GC_GETINFO, 0, (LPARAM)(GC_INFO *) &gci);
+
+ ::mir_free(gci.pszID);
+
+ //StringList users(gci.pszUsers, " ");
+
+ return gci.pszUsers;
} \ No newline at end of file
diff --git a/protocols/Skype/src/skype_contacts.cpp b/protocols/Skype/src/skype_contacts.cpp
index eae999ef92..116149cd55 100644
--- a/protocols/Skype/src/skype_contacts.cpp
+++ b/protocols/Skype/src/skype_contacts.cpp
@@ -531,16 +531,17 @@ bool CSkypeProto::IsProtoContact(HANDLE hContact)
HANDLE CSkypeProto::GetContactBySid(const char *sid)
{
- HANDLE hContact = db_find_first();
+ HANDLE hContact = ::db_find_first();
while (hContact)
{
if (this->IsProtoContact(hContact) && !this->IsChatRoom(hContact))
{
- if (::strcmp(sid, ::DBGetString(hContact, this->m_szModuleName, "sid")) == 0)
+ char *contactSid = ::DBGetString(hContact, this->m_szModuleName, "sid");
+ if (contactSid && ::strcmp(sid, contactSid) == 0)
return hContact;
}
- hContact = db_find_next(hContact);
+ hContact = ::db_find_next(hContact);
}
return 0;
@@ -721,6 +722,44 @@ void __cdecl CSkypeProto::LoadContactList(void*)
this->UpdateContactStatusMessage(hContact, contact);
}
+ CConversation::Refs conversations;
+ g_skype->GetConversationList(conversations);
+ for (uint i = 0; i < conversations.size(); i++)
+ {
+ CConversation::TYPE type;
+ conversations[i]->GetPropType(type);
+
+ CConversation::MY_STATUS status;
+ conversations[i]->GetPropMyStatus(status);
+ if (type == CConversation::CONFERENCE)
+ {
+ SEString data;
+
+ conversations[i]->GetPropIdentity(data);
+ char *cid = ::mir_strdup((const char *)data);
+
+ conversations[i]->GetPropDisplayname(data);
+ char *name = ::mir_utf8decodeA((const char *)data);
+
+ HANDLE hContact = this->AddChatRoomByID(cid, name);
+
+ CConversation::LOCAL_LIVESTATUS live;
+ conversations[i]->GetPropLocalLivestatus(live);
+
+ if (status == CConversation::CONSUMER)// && live != CConversation::NONE)
+ {
+ this->JoinToChat(cid, false);
+ }
+ }
+ }
+
+ /*CConversation::Refs conversations;
+ g_skype->GetConversationList(conversations);
+ for (uint i = 0; i < conversations.size(); i++)
+ {
+ conversations[i]->Delete();
+ }*/
+
// raise auth event for all non auth contacts
CContact::Refs authContacts;
g_skype->GetHardwiredContactGroup(CContactGroup::CONTACTS_WAITING_MY_AUTHORIZATION, this->authWaitList);
diff --git a/protocols/Skype/src/skype_dialogs.cpp b/protocols/Skype/src/skype_dialogs.cpp
index a2464e6843..fd41a16407 100644
--- a/protocols/Skype/src/skype_dialogs.cpp
+++ b/protocols/Skype/src/skype_dialogs.cpp
@@ -89,10 +89,20 @@ INT_PTR CALLBACK CSkypeProto::SkypeOptionsProc(HWND hwnd, UINT message, WPARAM w
SetDlgItemTextA(hwnd, IDC_PW, data);
::mir_free(data);
}
+ {
+ int port;
+ g_skype->GetInt(SETUPKEY_PORT, port);
+ SetDlgItemInt(hwnd, IDC_PORT, proto->GetSettingWord("Port", port), FALSE);
+ }
+ {
+ CheckDlgButton(hwnd, IDC_USE_ALT_PORTS, proto->GetSettingByte("UseAlternativePorts", 1));
+ }
if (proto->m_iStatus != ID_STATUS_OFFLINE) {
SendMessage(GetDlgItem(hwnd, IDC_SL), EM_SETREADONLY, 1, 0);
SendMessage(GetDlgItem(hwnd, IDC_PW), EM_SETREADONLY, 1, 0);
+ SendMessage(GetDlgItem(hwnd, IDC_PORT), EM_SETREADONLY, 1, 0);
+ SendMessage(GetDlgItem(hwnd, IDC_USE_ALT_PORTS), EM_SETREADONLY, 1, 0);
}
}
return TRUE;
@@ -105,6 +115,8 @@ INT_PTR CALLBACK CSkypeProto::SkypeOptionsProc(HWND hwnd, UINT message, WPARAM w
{
case IDC_SL:
case IDC_PW:
+ case IDC_PORT:
+ case IDC_USE_ALT_PORTS:
SendMessage(GetParent(hwnd), PSM_CHANGED, 0, 0);
}
}
@@ -125,6 +137,9 @@ INT_PTR CALLBACK CSkypeProto::SkypeOptionsProc(HWND hwnd, UINT message, WPARAM w
GetDlgItemTextA(hwnd, IDC_PW, data, sizeof(data));
proto->SetDecodeSettingString(NULL, SKYPE_SETTINGS_PASSWORD, data);
+ proto->SetSettingWord("Port", GetDlgItemInt(hwnd, IDC_PORT, NULL, FALSE));
+ proto->GetSettingByte("UseAlternativePorts", IsDlgButtonChecked( hwnd, IDC_USE_ALT_PORTS ) > 0);
+
proto->SetSettingByte("RememberPassword", true);
return TRUE;
@@ -471,13 +486,33 @@ INT_PTR CALLBACK CSkypeProto::InviteToChatProc(HWND hwndDlg, UINT msg, WPARAM wP
case CLN_NEWCONTACT:
if (param && (nmc->flags & (CLNF_ISGROUP | CLNF_ISINFO)) == 0)
{
- param->ppro->ChatValidateContact(nmc->hItem, nmc->hdr.hwndFrom);
+ char *contacts = NULL;
+ if (param->id)
+ {
+ HANDLE hContact = param->ppro->GetChatRoomByID(param->id);
+ if (hContact && ::DBGetContactSettingWord(hContact, param->ppro->m_szModuleName, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE)
+ {
+ contacts = param->ppro->GetChatUsers(param->id);
+ }
+ }
+ param->ppro->ChatValidateContact(nmc->hItem, nmc->hdr.hwndFrom, contacts);
}
break;
case CLN_LISTREBUILT:
if (param)
- param->ppro->ChatPrepare(NULL, nmc->hdr.hwndFrom);
+ {
+ char *contacts = NULL;
+ if (param->id)
+ {
+ HANDLE hContact = param->ppro->GetChatRoomByID(param->id);
+ if (hContact && ::DBGetContactSettingWord(hContact, param->ppro->m_szModuleName, "Status", ID_STATUS_OFFLINE) != ID_STATUS_OFFLINE)
+ {
+ contacts = param->ppro->GetChatUsers(param->id);
+ }
+ }
+ param->ppro->ChatPrepare(NULL, nmc->hdr.hwndFrom, contacts);
+ }
break;
}
}
@@ -511,12 +546,35 @@ INT_PTR CALLBACK CSkypeProto::InviteToChatProc(HWND hwndDlg, UINT msg, WPARAM wP
case IDOK:
{
- char sid[SKYPE_SID_LIMIT] = "";
HWND hwndList = ::GetDlgItem(hwndDlg, IDC_CCLIST);
- SEStringList inviteContacts;
- param->ppro->GetInviteContacts(NULL, hwndList, inviteContacts);
- param->ppro->StartChat(NULL, inviteContacts);
+ SEStringList invitedContacts;
+ param->ppro->GetInviteContacts(NULL, hwndList, invitedContacts);
+
+ CConversation::Ref conversation;
+ char *chatID = ::mir_strdup(param->id);
+ if (chatID)
+ {
+ g_skype->GetConversationByIdentity(chatID, conversation);
+ conversation->AddConsumers(invitedContacts);
+ }
+ else
+ {
+ chatID = param->ppro->StartChat(NULL);
+
+ g_skype->GetConversationByIdentity(chatID, conversation);
+ conversation->AddConsumers(invitedContacts);
+
+ /*SEString data;
+
+ conversation->GetPropIdentity(data);
+ char *cid = ::mir_strdup((const char *)data);
+
+ for (uint i = 0; i < invitedContacts.size(); i++)
+ {
+ param->ppro->AddChatContact(cid, invitedContacts[i]);
+ }*/
+ }
}
EndDialog(hwndDlg, IDOK);
diff --git a/protocols/Skype/src/skype_events.cpp b/protocols/Skype/src/skype_events.cpp
index a3a89b9a6e..61b9724cb8 100644
--- a/protocols/Skype/src/skype_events.cpp
+++ b/protocols/Skype/src/skype_events.cpp
@@ -22,7 +22,21 @@ int CSkypeProto::OnPreShutdown(WPARAM, LPARAM)
int CSkypeProto::OnContactDeleted(WPARAM wParam, LPARAM lParam)
{
- this->RevokeAuth(wParam, lParam);
+ HANDLE hContact = (HANDLE)wParam;
+ if (hContact && this->IsOnline())
+ {
+ if (this->IsChatRoom(hContact))
+ {
+ char *chatID = ::DBGetString(hContact, this->m_szModuleName, "ChatRoomID");
+ this->LeaveChat(chatID);
+
+ CConversation::Ref conversation;
+ g_skype->GetConversationByIdentity(chatID, conversation);
+ conversation->Delete();
+ }
+ else
+ this->RevokeAuth(wParam, lParam);
+ }
return 0;
}
@@ -38,7 +52,7 @@ void CSkypeProto::OnMessageSended(CConversation::Ref conversation, CMessage::Ref
char *sid = ::mir_strdup((const char*)data);
message->GetPropBodyXml(data);
- char *text = ::mir_strdup((const char*)data);
+ char *text = ::mir_utf8decodeA((const char*)data);
CConversation::TYPE type;
conversation->GetPropType(type);
@@ -62,9 +76,16 @@ void CSkypeProto::OnMessageSended(CConversation::Ref conversation, CMessage::Ref
else
{
conversation->GetPropIdentity(data);
- char *chatID = ::mir_utf8encode((const char*)data);
+ char *cid = ::mir_strdup((const char*)data);
+
+ /*HANDLE hContact = this->GetChatRoomByID(cid);
+ if ( !hContact || ::DBGetContactSettingWord(hContact, this->m_szModuleName, "Status", ID_STATUS_OFFLINE) == ID_STATUS_OFFLINE)
+ {
+ this->JoinChat(cid);
+ }*/
+ this->SendChatMessage(cid, sid, text);
- this->ChatEvent(chatID, sid, /*GC_EVENT_MESSAGE*/0x0040, text);
+ ::mir_free(cid);
}
}
@@ -86,7 +107,7 @@ void CSkypeProto::OnMessageReceived(CConversation::Ref conversation, CMessage::R
if (type == CConversation::DIALOG)
{
message->GetPropAuthorDisplayname(data);
- char *nick = ::mir_strdup((const char*)data);
+ char *nick = ::mir_utf8encode((const char*)data);
this->RaiseMessageReceivedEvent(
(DWORD)timestamp,
@@ -97,9 +118,16 @@ void CSkypeProto::OnMessageReceived(CConversation::Ref conversation, CMessage::R
else
{
conversation->GetPropIdentity(data);
- char *chatID = ::mir_strdup((const char*)data);
+ char *cid = ::mir_strdup((const char*)data);
+
+ /*HANDLE hContact = this->GetChatRoomByID(cid);
+ if ( !hContact || ::DBGetContactSettingWord(hContact, this->m_szModuleName, "Status", ID_STATUS_OFFLINE) == ID_STATUS_OFFLINE)
+ {
+ this->JoinChat(cid);
+ }*/
+ this->SendChatMessage(cid, sid, text);
- this->ChatEvent(chatID, sid, /*GC_EVENT_MESSAGE*/ 0x0040, text);
+ ::mir_free(cid);
}
/*const char *msg = (const char*)propValues[2];
@@ -119,11 +147,110 @@ void CSkypeProto::OnMessage(CConversation::Ref conversation, CMessage::Ref messa
CMessage::SENDING_STATUS sendingStatus;
message->GetPropSendingStatus(sendingStatus);
- if (messageType == CMessage::POSTED_TEXT)
+ switch (messageType)
{
+ case CMessage::POSTED_EMOTE:
+ case CMessage::POSTED_TEXT:
if (sendingStatus == CMessage::SENT)
this->OnMessageSended(conversation, message);
else if (!sendingStatus)
this->OnMessageReceived(conversation, message);
+ break;
+
+ case CMessage::ADDED_CONSUMERS:
+ {
+ SEString data;
+
+ conversation->GetPropIdentity(data);
+ char *cid = ::mir_strdup(data);
+
+ HANDLE hContact = this->GetChatRoomByID(cid);
+ if ( !hContact || ::DBGetContactSettingWord(hContact, this->m_szModuleName, "Status", ID_STATUS_OFFLINE) == ID_STATUS_OFFLINE)
+ {
+ this->StartChat(cid);
+
+ CParticipant::Refs participants;
+ conversation->GetParticipants(participants, CConversation::OTHER_CONSUMERS);
+ for (uint i = 0; i < participants.size(); i++)
+ {
+ participants[i]->GetPropIdentity(data);
+ this->AddChatContact(cid, data);
+ }
+ }
+
+ {
+ message->GetPropIdentities(data);
+
+ StringList alreadyInChat(this->GetChatUsers(cid), " ");
+ StringList needToAdd(data, " ");
+
+ for (int i = 0; i < needToAdd.getCount(); i++)
+ {
+ char *sid = needToAdd[i];
+ if (::stricmp(sid, this->login) != 0 && !alreadyInChat.contains(sid))
+ this->AddChatContact(cid, sid);
+ }
+ }
+ }
+ break;
+
+ case CMessage::RETIRED:
+ {
+ SEString data;
+
+ conversation->GetPropIdentity(data);
+ char *cid = ::mir_strdup(data);
+
+ StringList alreadyInChat(this->GetChatUsers(cid), " ");
+
+ message->GetPropAuthor(data);
+ char *sid = ::mir_strdup(data);
+ if (::stricmp(sid, this->login) != 0 && alreadyInChat.contains(sid))
+ this->RemoveChatContact(cid, sid);
+ }
+ break;
+ case CMessage::RETIRED_OTHERS:
+ {
+ SEString data;
+
+ conversation->GetPropIdentity(data);
+ char *cid = ::mir_strdup(data);
+
+ message->GetPropIdentities(data);
+
+ StringList alreadyInChat(this->GetChatUsers(cid), " ");
+ StringList needToKick(data, " ");
+
+ for (int i = 0; i < needToKick.getCount(); i++)
+ {
+ char *sid = needToKick[i];
+ if (::stricmp(sid, this->login) != 0 && !alreadyInChat.contains(sid))
+ this->KickChatContact(cid, sid);
+ }
+ }
+ break;
+
+ case CMessage::SPAWNED_CONFERENCE:
+ {
+ SEString data;
+ conversation->GetPropIdentity(data);
+ char *cid = ::mir_strdup(data);
+
+ /*HANDLE hContact = this->GetChatRoomByID(cid);
+ if ( !hContact || ::DBGetContactSettingWord(hContact, this->m_szModuleName, "Status", ID_STATUS_OFFLINE) == ID_STATUS_OFFLINE)
+ {
+ this->JoinChat(cid);
+ }*/
+ }
+ break;
+
+ //case CMessage::REQUESTED_AUTH:
+ // break;
+
+ //case CMessage::GRANTED_AUTH:
+ // break;
+
+ //case CMessage::BLOCKED:
+ // break;
}
-} \ No newline at end of file
+}
diff --git a/protocols/Skype/src/skype_proto.cpp b/protocols/Skype/src/skype_proto.cpp
index 1e33a9a5a7..54d43d56c9 100644
--- a/protocols/Skype/src/skype_proto.cpp
+++ b/protocols/Skype/src/skype_proto.cpp
@@ -29,6 +29,11 @@ CSkypeProto::CSkypeProto(const char* protoName, const TCHAR* userName)
this->InitNetLib();
this->InitCustomFolders();
+
+ //
+ g_skype->SetOnMessageCallback(
+ (CSkype::OnMessaged)&CSkypeProto::OnMessage,
+ this);
}
CSkypeProto::~CSkypeProto()
@@ -243,7 +248,7 @@ int __cdecl CSkypeProto::SendMsg(HANDLE hContact, int flags, const char* msg)
if (conversation)
{
Message::Ref message;
- conversation->PostText(msg, message);
+ conversation->PostText(::mir_utf8encode(msg), message);
}
this->SendBroadcastAsync(
@@ -358,10 +363,6 @@ int __cdecl CSkypeProto::OnEvent(PROTOEVENTTYPE eventType, WPARAM wParam, LPA
void __cdecl CSkypeProto::SignInAsync(void*)
{
- g_skype->SetOnMessageCallback(
- (CSkype::OnMessaged)&CSkypeProto::OnMessage,
- this);
-
this->SetStatus(this->m_iDesiredStatus);
this->LoadOwnInfo(this);
@@ -393,12 +394,17 @@ bool CSkypeProto::SignIn(bool isReadPassword)
(CAccount::OnAccountChanged)&CSkypeProto::OnAccountChanged,
this);
//
+ int port;
+ g_skype->GetInt(SETUPKEY_PORT, port);
+ g_skype->SetInt(SETUPKEY_PORT, this->GetSettingWord("Port", port));
+ g_skype->SetInt(SETUPKEY_DISABLE_PORT80, (int)!this->GetSettingByte("UseAlternativePorts", 1));
+ //
if (this->hNetlibUser)
{
NETLIBUSERSETTINGS nlus = { sizeof(NETLIBUSERSETTINGS) };
- if (
- !::CallService(MS_NETLIB_GETUSERSETTINGS, (WPARAM)this->hNetlibUser, (LPARAM)&nlus) &&
- nlus.useProxy)
+ ::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);
@@ -413,7 +419,12 @@ bool CSkypeProto::SignIn(bool isReadPassword)
if (nlus.useProxyAuth)
{
g_skype->SetStr(SETUPKEY_HTTPS_PROXY_USER, nlus.szProxyAuthUser);
- g_skype->SetStr(SETUPKEY_HTTPS_PROXY_PWD, nlus.szProxyAuthPassword);
+
+ char *encodedPass = new char[MAX_PATH];
+
+ CSkypeProto::Base64Encode(nlus.szProxyAuthPassword, encodedPass, MAX_PATH);
+
+ g_skype->SetStr(SETUPKEY_HTTPS_PROXY_PWD, encodedPass);
}
break;
diff --git a/protocols/Skype/src/skype_proto.h b/protocols/Skype/src/skype_proto.h
index ba35c31fa5..294a1d1a0b 100644
--- a/protocols/Skype/src/skype_proto.h
+++ b/protocols/Skype/src/skype_proto.h
@@ -11,6 +11,59 @@ typedef INT_PTR (__cdecl CSkypeProto::* SkypeServiceFunc)(WPARAM, LPARAM);
typedef int (__cdecl CSkypeProto::* SkypeEventFunc)(WPARAM, LPARAM);
typedef INT_PTR (__cdecl CSkypeProto::* SkypeServiceFuncParam)(WPARAM, LPARAM, LPARAM);
+struct StringList : public LIST<char>
+{
+ static int compare(const char* p1, const char* p2)
+ { return _stricmp(p1, p2); }
+
+ StringList() : LIST<char>(2, compare) {}
+ StringList(const char* string, const char *delimeters) : LIST<char>(2, compare)
+ {
+ char *data = ::mir_strdup(string);
+ if (data)
+ {
+ char *p = ::strtok(data, delimeters);
+ if (p)
+ {
+ this->insert(::mir_strdup(p));
+ while (p = strtok(NULL, delimeters))
+ {
+ this->insert(::mir_strdup(p));
+ }
+ }
+ ::mir_free(data);
+ }
+ }
+ ~StringList() { destroy(); }
+
+ void destroy( void )
+ {
+ for (int i=0; i < count; i++)
+ mir_free(items[i]);
+
+ List_Destroy((SortedList*)this);
+ }
+
+ int insertn(const char* p) { return insert(mir_strdup(p)); }
+
+ int remove(int idx)
+ {
+ mir_free(items[idx]);
+ return List_Remove((SortedList*)this, idx);
+ }
+
+ int remove(const char* p)
+ {
+ int idx;
+ return List_GetIndex((SortedList*)this, (char*)p, &idx) == 1 ? remove(idx) : -1;
+ }
+
+ bool contains(char* p)
+ {
+ return indexOf(p) >= 0;
+ }
+};
+
struct _tag_iconList
{
wchar_t* Description;
@@ -194,15 +247,26 @@ protected:
// chat
bool IsChatRoom(HANDLE hContact);
+ HANDLE GetChatRoomByID(const char *cid);
+ HANDLE AddChatRoomByID(const char* cid, const char* name, DWORD flags = 0);
- void ChatValidateContact(HANDLE hItem, HWND hwndList);
- void ChatPrepare(HANDLE hItem, HWND hwndList);
- void GetInviteContacts(HANDLE hItem, HWND hwndList, SEStringList &inviteContacts);
+ char *CSkypeProto::GetChatUsers(const char *cid);
+
+ void ChatValidateContact(HANDLE hItem, HWND hwndList, const char *contacts);
+ void ChatPrepare(HANDLE hItem, HWND hwndList, const char *contacts);
+
+ void GetInviteContacts(HANDLE hItem, HWND hwndList, SEStringList &invitedContacts);
void InitChat();
- void StartChat(HANDLE hContact, SEStringList &invitedContacts);
- void ChatEvent(const char *chatID, const char *sid, int evt, const char* msg);
- void ChatLeave(const char *chatID);
+ char *StartChat(const char *cid);
+ void JoinToChat(const char *cid, bool showWindow = true);
+ void LeaveChat(const char *cid);
+
+ void RaiseChatEvent(const char *cid, const char *sid, int evt, const char *message = NULL);
+ void SendChatMessage(const char *cid, const char *sid, const char *message);
+ void AddChatContact(const char *cid, const char *sid);
+ void KickChatContact(const char *cid, const char *sid);
+ void RemoveChatContact(const char *cid, const char *sid);
INT_PTR __cdecl OnJoinChat(WPARAM wParam, LPARAM);
INT_PTR __cdecl OnLeaveChat(WPARAM wParam, LPARAM);
@@ -289,6 +353,10 @@ protected:
void ShowNotification(const char *nick, const wchar_t *message, int flags = 0);
+ //
+ static char CharBase64[];
+ static ULONG Base64Encode(char *inputString, char *outputBuffer, SIZE_T nMaxLength);
+
// instances
static LIST<CSkypeProto> instanceList;
static int CompareProtos(const CSkypeProto *p1, const CSkypeProto *p2);
@@ -360,9 +428,9 @@ protected:
WORD GetSettingWord(HANDLE hContact, const char *setting, WORD errorValue = 0);
DWORD GetSettingDword(const char *setting, DWORD defVal = 0);
DWORD GetSettingDword(HANDLE hContact, const char *setting, DWORD errorValue = 0);
- wchar_t* GetSettingString(const char *setting, wchar_t* errorValue = NULL);
- wchar_t* GetSettingString(HANDLE hContact, const char *setting, wchar_t* errorValue = NULL);
- char* GetDecodeSettingString(HANDLE hContact, const char *setting, char* errorValue = NULL);
+ wchar_t *GetSettingString(const char *setting, wchar_t* errorValue = NULL);
+ wchar_t *GetSettingString(HANDLE hContact, const char *setting, wchar_t* errorValue = NULL);
+ char *GetDecodeSettingString(HANDLE hContact, const char *setting, char* errorValue = NULL);
//
bool SetSettingByte(const char *setting, BYTE value);
bool SetSettingByte(HANDLE hContact, const char *setting, BYTE value);
diff --git a/protocols/Skype/src/skype_subclassing.cpp b/protocols/Skype/src/skype_subclassing.cpp
index 5eb2882e4d..6289bc1f98 100644
--- a/protocols/Skype/src/skype_subclassing.cpp
+++ b/protocols/Skype/src/skype_subclassing.cpp
@@ -55,8 +55,6 @@ void CSkype::OnMessage (
if (this->proto)
(proto->*onMessagedCallback)(conversation->ref(), message->ref());
-
-
}
void CSkype::SetOnMessageCallback(OnMessaged callback, CSkypeProto* proto)
@@ -99,11 +97,6 @@ void CContactGroup::SetOnContactListChangedCallback(OnContactListChanged callbac
this->callback = callback;
}
-//bool CContactGroup::Contains(const ContactRef& contact)
-//{
-// return this->ContactList.contains(contact);
-//}
-
void CContactGroup::OnChange(const ContactRef& contact)
{
if (this->proto)
@@ -132,10 +125,6 @@ void CContactSearch::OnChange(int prop)
(proto->*SearchCompletedCallback)(this->hSearch);
}
}
-
- //SEString value = GetProp(prop);
- //List_String dbg = getPropDebug(prop, value);
- //fprintf(stdout,"CONTACTSEARCH.%d:%s = %s\n", getOID(), (const char*)dbg[1], (const char*)dbg[2]);
}
void CContactSearch::OnNewResult(const ContactRef& contact, const uint& rankValue)
@@ -197,13 +186,13 @@ void CContact::OnChange(int prop)
CConversation::CConversation(unsigned int oid, SERootObject* root) : Conversation(oid, root)
{
this->proto = NULL;
- this->callback == NULL;
+ this->messageReceivedCallback = NULL;
}
void CConversation::OnMessage(const MessageRef & message)
{
if (this->proto)
- (proto->*callback)(message->ref());
+ (proto->*messageReceivedCallback)(message->ref());
}
CConversation::Ref CConversation::FindBySid(CSkype *skype, SEString sid)
@@ -220,7 +209,7 @@ CConversation::Ref CConversation::FindBySid(CSkype *skype, SEString sid)
void CConversation::SetOnMessageReceivedCallback(OnMessageReceived callback, CSkypeProto* proto)
{
this->proto = proto;
- this->callback = callback;
+ this->messageReceivedCallback = callback;
}
// CMessage
diff --git a/protocols/Skype/src/skype_subclassing.h b/protocols/Skype/src/skype_subclassing.h
index b2798316e9..0993cde7d9 100644
--- a/protocols/Skype/src/skype_subclassing.h
+++ b/protocols/Skype/src/skype_subclassing.h
@@ -44,7 +44,8 @@ public:
private:
CSkypeProto* proto;
- OnMessageReceived callback;
+ OnMessageReceived messageReceivedCallback;
+
void OnMessage(const MessageRef & message);
};
@@ -105,11 +106,8 @@ public:
typedef DRefs<CContactGroup, ContactGroup> Refs;
CContactGroup(unsigned int oid, SERootObject* root);
- //CContact::Refs ContactList;
void SetOnContactListChangedCallback(OnContactListChanged callback, CSkypeProto* proto);
- //bool Contains(const ContactRef& contact);
-
private:
CSkypeProto* proto;
OnContactListChanged callback;
diff --git a/protocols/Skype/src/skype_utils.cpp b/protocols/Skype/src/skype_utils.cpp
index 73df520aa0..5fdcb0dff1 100644
--- a/protocols/Skype/src/skype_utils.cpp
+++ b/protocols/Skype/src/skype_utils.cpp
@@ -473,4 +473,55 @@ void CSkypeProto::ShowNotification(const char *nick, const wchar_t *message, int
::CallService(MS_POPUP_ADDPOPUPT, (WPARAM)&ppd, 0);
}
+}
+
+char CSkypeProto::CharBase64[] =
+{
+ 'A','B','C','D','E','F','G','H','I','J','K','L','M ','N','O','P',
+ 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c ','d','e','f',
+ 'g','h','i','j','k','l','m','n','o','p','q','r','s ','t','u','v',
+ 'w','x','y','z','0','1','2','3','4','5','6','7','8 ','9','+','/'
+};
+
+ULONG CSkypeProto::Base64Encode(char *inputString, char *outputBuffer, SIZE_T nMaxLength)
+{
+ int outpos = 0;
+ char chr[3], enc[4];
+
+ for (uint i = 0; i < ::strlen(inputString); i += 3)
+ {
+ if (outpos + 4 >= nMaxLength)
+ break;
+
+ chr[0] = inputString[i];
+ chr[1] = inputString[i+1];
+ chr[2] = inputString[i+2];
+
+ enc[0] = chr[0] >> 2;
+ enc[1] = ((chr[0] & 0x03) << 4) | (chr[1] >> 4);
+ enc[2] = ((chr[1] & 0x0F) << 2) | (chr[2] >> 6);
+ enc[3] = chr[2] & 0x3F;
+
+ outputBuffer[outpos++] = CSkypeProto::CharBase64[enc[0]];
+ outputBuffer[outpos++] = CSkypeProto::CharBase64[enc[1]];
+
+ if (i + 1 >= ::strlen(inputString))
+ {
+ outputBuffer[outpos++] = '=';
+ outputBuffer[outpos++] = '=';
+ }
+ else if (i + 2 >= ::strlen(inputString))
+ {
+ outputBuffer[outpos++] = CSkypeProto::CharBase64[enc[2]];
+ outputBuffer[outpos++] = '=';
+ }
+ else
+ {
+ outputBuffer[outpos++] = CSkypeProto::CharBase64[enc[2]];
+ outputBuffer[outpos++] = CSkypeProto::CharBase64[enc[3]];
+ }
+ }
+
+ outputBuffer[outpos] = 0;
+ return outpos;
} \ No newline at end of file