From b28379050fa05a1a6642548d9d31c4d7d2779815 Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Tue, 14 May 2013 20:52:44 +0000 Subject: - added contact sending (via SendReceiveContacts) and receiving - some few bug fixed git-svn-id: http://svn.miranda-ng.org/main/trunk@4653 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Skype/src/resource.h | 56 ++++++++++---------- protocols/Skype/src/skype.h | 9 ++-- protocols/Skype/src/skype_contacts.cpp | 92 +++++++++++++++++++++++++++++++++ protocols/Skype/src/skype_events.cpp | 6 ++- protocols/Skype/src/skype_icons.cpp | 1 + protocols/Skype/src/skype_instances.cpp | 2 +- protocols/Skype/src/skype_messages.cpp | 6 ++- protocols/Skype/src/skype_proto.cpp | 69 +++++++++++++++++++++++-- protocols/Skype/src/skype_proto.h | 11 ++-- protocols/Skype/src/skype_runtime.cpp | 28 +++++----- protocols/Skype/src/skype_transfers.cpp | 2 +- protocols/Skype/src/skype_utils.cpp | 2 +- 12 files changed, 225 insertions(+), 59 deletions(-) (limited to 'protocols/Skype/src') diff --git a/protocols/Skype/src/resource.h b/protocols/Skype/src/resource.h index df27045a46..94714f7290 100644 --- a/protocols/Skype/src/resource.h +++ b/protocols/Skype/src/resource.h @@ -20,6 +20,7 @@ #define IDI_CALL 108 #define IDI_CONF_INVITE 109 #define IDI_CONF_SPAWN 110 +#define IDI_SEND_CONTACTS 111 #define IDC_CCLIST 173 #define IDC_EDITSCR 174 #define IDC_ADDSCR 175 @@ -30,43 +31,40 @@ #define IDC_SAVEPASSWORD 1005 #define IDC_PASSWORD 1006 #define IDC_INSTRUCTION 1007 -#define IDC_SID 1008 -#define IDC_STATUSTEXT 1009 -#define IDC_ONLINESINCE 1010 -#define IDC_LASTEVENTDATE 1011 -#define IDC_PASSWORD3 1011 -#define IDC_LASTPROFILECHANGE 1012 +#define IDC_INSTRUCTION2 1008 +#define IDC_INSTRUCTION3 1009 +#define IDC_SID 1010 +#define IDC_STATUSTEXT 1011 +#define IDC_ONLINESINCE 1012 +#define IDC_LASTEVENTDATE 1013 +#define IDC_PASSWORD3 1014 +#define IDC_LASTPROFILECHANGE 1015 #define IDC_PORT 1016 #define IDC_USE_ALT_PORTS 1017 #define IDC_REGISTER 1018 #define IDC_CHANGE_PWD 1019 #define IDC_DEFAULT_GROUP 1020 #define IDC_GROUP 1021 -#define IDC_INSTRUCTION2 1022 #define IDC_PASSWORD2 1023 -#define IDC_INSTRUCTION3 1024 #define IDC_FULLNAME 1025 -#define IDC_EMAIL1 1025 -#define IDC_BIRTH_DAY 1026 -#define IDC_EMAIL2 1026 -#define IDC_BIRTH_MONTH 1027 -#define IDC_EMAIL3 1027 -#define IDC_BIRTH_YEAR 1028 -#define IDC_MOBPHONE 1028 -#define IDC_GENDER 1029 -#define IDC_HOMEPHONE 1029 -#define IDC_HOMEPAGE 1030 -#define IDC_HOMEPHONE2 1030 -#define IDC_OFFICEPHONE 1030 -#define IDC_LANGUAGE 1031 -#define IDC_ABOUT 1034 -#define IDC_ABOUT2 1035 -#define IDC_MOOD 1035 -#define IDC_CITY 1036 -#define IDC_STATE 1037 -#define IDC_COUNTRY 1038 -#define IDC_COUNTRY2 1039 -#define IDC_TIMEZONE 1039 +#define IDC_EMAIL1 1026 +#define IDC_EMAIL2 1027 +#define IDC_EMAIL3 1028 +#define IDC_BIRTH_DAY 1029 +#define IDC_BIRTH_MONTH 1030 +#define IDC_BIRTH_YEAR 1031 +#define IDC_MOBPHONE 1032 +#define IDC_GENDER 1033 +#define IDC_HOMEPHONE 1034 +#define IDC_HOMEPAGE 1035 +#define IDC_OFFICEPHONE 1036 +#define IDC_LANGUAGE 1037 +#define IDC_ABOUT 1038 +#define IDC_MOOD 1039 +#define IDC_CITY 1040 +#define IDC_STATE 1041 +#define IDC_COUNTRY 1042 +#define IDC_TIMEZONE 1043 // Next default values for new objects // diff --git a/protocols/Skype/src/skype.h b/protocols/Skype/src/skype.h index ceeeede69f..27d7fcfed2 100644 --- a/protocols/Skype/src/skype.h +++ b/protocols/Skype/src/skype.h @@ -54,11 +54,12 @@ #define SKYPE_SEARCH_BYEMAIL 1002 #define SKYPE_SEARCH_BYNAMES 1003 -#define BBB_ID_CONF_INVITE 2001 -#define BBB_ID_CONF_SPAWN 2002 +#define BBB_ID_CONF_INVITE 2001 +#define BBB_ID_CONF_SPAWN 2002 -#define SKYPE_DB_EVENT_TYPE_EMOTE 10001 -#define SKYPE_DB_EVENT_TYPE_CALL 10010 +#define SKYPE_DB_EVENT_TYPE_EMOTE 10001 +#define SKYPE_DB_EVENT_TYPE_CONTACTS 10002 +#define SKYPE_DB_EVENT_TYPE_CALL 10010 #define CMI_AUTH_REVOKE 1 #define CMI_AUTH_REQUEST 2 diff --git a/protocols/Skype/src/skype_contacts.cpp b/protocols/Skype/src/skype_contacts.cpp index b0909f8435..ff50d880f5 100644 --- a/protocols/Skype/src/skype_contacts.cpp +++ b/protocols/Skype/src/skype_contacts.cpp @@ -495,4 +495,96 @@ void __cdecl CSkypeProto::SearchByNamesAsync(void* arg) search->BlockWhileSearch(); search->Release(); +} + +void CSkypeProto::OnContactsReceived(const ConversationRef &conversation, const MessageRef &message) +{ + CContact::Refs contacts; + message->GetContacts(contacts); + + uint timestamp; + message->GetPropTimestamp(timestamp); + + CMessage::TYPE messageType; + message->GetPropType(messageType); + + SEString data; + message->GetPropAuthor(data); + + CContact::Ref author; + this->GetContact(data, author); + + HANDLE hContact = this->AddContact(author); + + SEBinary guid; + message->GetPropGuid(guid); + ReadMessageParam param = { guid, messageType }; + + PROTORECVEVENT pre; + pre.flags = PREF_UTF; + pre.lParam = (LPARAM)¶m; + pre.timestamp = timestamp; + + int msgSize = 1; + pre.szMessage = (char *)::mir_alloc(msgSize); + pre.szMessage[0] = 0; + + int len = 0; + char* pCur = &pre.szMessage[0]; + + for (size_t i = 0; i < contacts.size(); i ++) + { + contacts[i]->GetIdentity(data); + if ( ::lstrcmpi(mir_ptr(::mir_utf8decodeW(data)), this->login) != 0) + this->AddContact(contacts[i]); + } + + char *text = ::mir_utf8encode(::Translate("Contacts received")); + + this->AddDBEvent( + hContact, + SKYPE_DB_EVENT_TYPE_CONTACTS, + timestamp, + PREF_UTF, + (DWORD)::strlen(text) + 1, + (PBYTE)text); +} + +void CSkypeProto::OnContactsSent(const ConversationRef &conversation, const MessageRef &message) +{ + SEString data; + + CMessage::TYPE messageType; + message->GetPropType(messageType); + + uint timestamp; + message->GetPropTimestamp(timestamp); + + CMessage::SENDING_STATUS status; + message->GetPropSendingStatus(status); + + CParticipant::Refs participants; + conversation->GetParticipants(participants, CConversation::OTHER_CONSUMERS); + participants[0]->GetPropIdentity(data); + + CContact::Ref receiver; + this->GetContact(data, receiver); + + HANDLE hContact = this->AddContact(receiver); + this->SendBroadcast( + hContact, + ACKTYPE_CONTACTS, + status == CMessage::FAILED_TO_SEND ? ACKRESULT_FAILED : ACKRESULT_SUCCESS, + (HANDLE)message->getOID(), 0); +} + +void CSkypeProto::OnContactsEvent(const ConversationRef &conversation, const MessageRef &message) +{ + SEString author; + message->GetPropAuthor(author); + + if (::wcsicmp(mir_ptr(::mir_utf8decodeW(author)), this->login) == 0) + this->OnContactsSent(conversation, message); + else + this->OnContactsReceived(conversation, message); } \ No newline at end of file diff --git a/protocols/Skype/src/skype_events.cpp b/protocols/Skype/src/skype_events.cpp index 7eb31cb246..b86782a875 100644 --- a/protocols/Skype/src/skype_events.cpp +++ b/protocols/Skype/src/skype_events.cpp @@ -231,7 +231,11 @@ void CSkypeProto::OnMessage ( break; case CMessage::POSTED_FILES: - this->OnFile(conversation, message); + this->OnFileEvent(conversation, message); + break; + + case CMessage::POSTED_CONTACTS: + this->OnContactsEvent(conversation, message); break; //case CMessage::REQUESTED_AUTH: diff --git a/protocols/Skype/src/skype_icons.cpp b/protocols/Skype/src/skype_icons.cpp index e7bf1249d0..edd4f0d316 100644 --- a/protocols/Skype/src/skype_icons.cpp +++ b/protocols/Skype/src/skype_icons.cpp @@ -10,6 +10,7 @@ _tag_iconList CSkypeProto::IconList[] = { LPGENT("Revoke authorization"), "authRevoke", IDI_AUTH_REVOKE }, { LPGENT("Request authorization"), "authRequest", IDI_AUTH_REQUEST }, { LPGENT("Grant authorization"), "authGrant", IDI_AUTH_GRANT }, + { LPGENT("Send contact"), "sendContacts", IDI_SEND_CONTACTS }, }; void CSkypeProto::InitIcons() diff --git a/protocols/Skype/src/skype_instances.cpp b/protocols/Skype/src/skype_instances.cpp index 5a49149ea8..0b83b767c6 100644 --- a/protocols/Skype/src/skype_instances.cpp +++ b/protocols/Skype/src/skype_instances.cpp @@ -36,7 +36,7 @@ CSkypeProto* CSkypeProto::InitSkypeProto(const char* protoName, const wchar_t* u return NULL; } - TransportInterface::Status status = ppro->init(keyPair, "127.0.0.1", ppro->runtimePort); + TransportInterface::Status status = ppro->init(keyPair, "127.0.0.1", ppro->skypeKitPort, 0, 1); if (status != TransportInterface::OK) { CSkypeProto::ShowNotification(::TranslateT("SkypeKit did not initialize.")); diff --git a/protocols/Skype/src/skype_messages.cpp b/protocols/Skype/src/skype_messages.cpp index 356224f5fd..ce8917d1db 100644 --- a/protocols/Skype/src/skype_messages.cpp +++ b/protocols/Skype/src/skype_messages.cpp @@ -65,8 +65,12 @@ void CSkypeProto::OnMessageReceived(const ConversationRef &conversation, const M if (this->IsMessageInDB(hContact, timestamp, guid)) return; + DWORD flags = PREF_UTF; + if (status != CMessage::UNCONSUMED_NORMAL) + flags |= PREF_CREATEREAD; + PROTORECVEVENT recv; - recv.flags = PREF_UTF; + recv.flags = flags; recv.lParam = (LPARAM)¶m; recv.timestamp = timestamp; recv.szMessage = ::mir_strdup(text); diff --git a/protocols/Skype/src/skype_proto.cpp b/protocols/Skype/src/skype_proto.cpp index 6044bd6343..6e437a8cea 100644 --- a/protocols/Skype/src/skype_proto.cpp +++ b/protocols/Skype/src/skype_proto.cpp @@ -18,6 +18,11 @@ CSkypeProto::CSkypeProto(const char* protoName, const TCHAR* userName) : Skype(1 dbEventType.descr = "Skype emote"; ::CallService(MS_DB_EVENT_REGISTERTYPE, 0, (LPARAM)&dbEventType); + dbEventType.eventType = SKYPE_DB_EVENT_TYPE_CONTACTS; + dbEventType.descr = "Skype contacts"; + dbEventType.eventIcon = CSkypeProto::GetIconHandle("sendContacts"); + ::CallService(MS_DB_EVENT_REGISTERTYPE, 0, (LPARAM)&dbEventType); + dbEventType.eventType = SKYPE_DB_EVENT_TYPE_CALL; dbEventType.descr = "Skype call"; dbEventType.eventIcon = CSkypeProto::GetIconHandle("call"); @@ -218,7 +223,7 @@ DWORD_PTR __cdecl CSkypeProto:: GetCaps(int type, HANDLE hContact) { case PFLAGNUM_1: return PF1_IM | PF1_FILE | PF1_BASICSEARCH | PF1_ADDSEARCHRES | PF1_SEARCHBYEMAIL | PF1_SEARCHBYNAME | - PF1_AUTHREQ | PF1_CHAT | PF1_SERVERCLIST/* | PF1_ADDSEARCHRES | F1_CONTACT*/; + PF1_AUTHREQ | PF1_CHAT | PF1_SERVERCLIST | PF1_CONTACT/* | PF1_ADDSEARCHRES*/; case PFLAGNUM_2: case PFLAGNUM_3: return PF2_ONLINE | PF2_SHORTAWAY | PF2_HEAVYDND | PF2_INVISIBLE | PF2_OUTTOLUNCH; @@ -229,6 +234,8 @@ DWORD_PTR __cdecl CSkypeProto:: GetCaps(int type, HANDLE hContact) return PF2_OUTTOLUNCH; case PFLAG_UNIQUEIDTEXT: return (DWORD_PTR)::Translate("Skype Name"); + case PFLAG_MAXCONTACTSPERPACKET: + return 1024; case PFLAG_UNIQUEIDSETTING: return (DWORD_PTR)SKYPE_SETTINGS_LOGIN; default: @@ -276,13 +283,25 @@ HWND __cdecl CSkypeProto::SearchAdvanced( HWND owner ) { return 0; } HWND __cdecl CSkypeProto::CreateExtendedSearchUI( HWND owner ){ return 0; } -int __cdecl CSkypeProto::RecvContacts( HANDLE hContact, PROTORECVEVENT* ) { return 0; } +int __cdecl CSkypeProto::RecvContacts( HANDLE hContact, PROTORECVEVENT* pre) +{ + this->Log(L"Incoming contacts"); + ::db_unset(hContact, "CList", "Hidden"); + + return (INT_PTR)this->AddDBEvent( + hContact, + EVENTTYPE_CONTACTS, + pre->timestamp, + DBEF_UTF | ((pre->flags & PREF_CREATEREAD) ? DBEF_READ : 0), + pre->lParam, + (PBYTE)pre->szMessage); +} -int __cdecl CSkypeProto::RecvFile( HANDLE hContact, PROTORECVFILET* evt) +int __cdecl CSkypeProto::RecvFile( HANDLE hContact, PROTORECVFILET* pre) { this->Log(L"Incoming file transfer"); ::db_unset(hContact, "CList", "Hidden"); - return ::Proto_RecvFile(hContact, evt); + return ::Proto_RecvFile(hContact, pre); } int __cdecl CSkypeProto::RecvMsg(HANDLE hContact, PROTORECVEVENT* pre) @@ -309,7 +328,47 @@ int __cdecl CSkypeProto::RecvMsg(HANDLE hContact, PROTORECVEVENT* pre) int __cdecl CSkypeProto::RecvUrl(HANDLE hContact, PROTORECVEVENT *) { return 0; } -int __cdecl CSkypeProto::SendContacts(HANDLE hContact, int flags, int nContacts, HANDLE *hContactsList) { return 0; } +int __cdecl CSkypeProto::SendContacts(HANDLE hContact, int flags, int nContacts, HANDLE *hContactsList) +{ + if (this->IsOnline() && hContact && hContactsList) + { + this->Log(L"Outcoming contacts"); + SEStringList targets; + mir_ptr sid(::db_get_wsa(hContact, this->m_szModuleName, SKYPE_SETTINGS_LOGIN)); + targets.append((char *)mir_ptr(::mir_utf8encodeW(sid))); + + CConversation::Ref conversation; + this->GetConversationByParticipants(targets, conversation); + + CContact::Refs contacts; + for (int i = 0; i < nContacts; i++) + { + CContact::Ref contact; + + mir_ptr csid(::db_get_wsa(hContactsList[i], this->m_szModuleName, SKYPE_SETTINGS_LOGIN)); + this->GetContact((char *)mir_ptr(::mir_utf8encodeW(csid)), contact); + contacts.append(contact); + } + + time_t timestamp = time(NULL); + + if ( !conversation->PostContacts(contacts)) + return 0; + + // todo: bad hack + CMessage::Refs msgs; + this->GetMessageListByType(Message::POSTED_CONTACTS, true, msgs, timestamp); + + if (msgs.size() == 0) + return 0; + + CMessage::Ref lastMsg = msgs[msgs.size() - 1]; + + return lastMsg->getOID(); + } + + return 0; +} HANDLE __cdecl CSkypeProto::SendFile(HANDLE hContact, const TCHAR *szDescription, TCHAR **ppszFiles) { diff --git a/protocols/Skype/src/skype_proto.h b/protocols/Skype/src/skype_proto.h index edc3e76e9c..e7681806b6 100644 --- a/protocols/Skype/src/skype_proto.h +++ b/protocols/Skype/src/skype_proto.h @@ -179,7 +179,8 @@ private: const MessageRef & supersedesHistoryMessage, const ConversationRef & conversation); - PROCESS_INFORMATION pi; + int skypeKitPort; + PROCESS_INFORMATION skypeKitProcessInfo; protected: CAccount::Ref account; @@ -243,8 +244,13 @@ protected: void OnMessageSent(const ConversationRef &conversation, const MessageRef &message); void OnMessageReceived(const ConversationRef &conversation, const MessageRef &message); + // contacts + void OnContactsEvent(const ConversationRef &conversation, const MessageRef &message); + void OnContactsSent(const ConversationRef &conversation, const MessageRef &message); + void OnContactsReceived(const ConversationRef &conversation, const MessageRef &message); + // transfer - void OnFile(const ConversationRef &conversation, const MessageRef &message); + void OnFileEvent(const ConversationRef &conversation, const MessageRef &message); void OnTransferChanged(CTransfer::Ref transfer, int prop); // chat @@ -453,7 +459,6 @@ protected: static INT_PTR CALLBACK HomeSkypeDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam); // skype runtime - int runtimePort; char *LoadKeyPair(); int StartSkypeRuntime(const wchar_t *profileName); void CSkypeProto::StopSkypeRuntime(); diff --git a/protocols/Skype/src/skype_runtime.cpp b/protocols/Skype/src/skype_runtime.cpp index a9588d8ff1..be83b788ad 100644 --- a/protocols/Skype/src/skype_runtime.cpp +++ b/protocols/Skype/src/skype_runtime.cpp @@ -46,7 +46,7 @@ int CSkypeProto::StartSkypeRuntime(const wchar_t *profileName) STARTUPINFO cif = {0}; cif.cb = sizeof(STARTUPINFO); cif.dwFlags = STARTF_USESHOWWINDOW; - cif.wShowWindow = SW_HIDE; + cif.wShowWindow = SW_HIDE; wchar_t fileName[MAX_PATH]; ::GetModuleFileName(g_hInstance, fileName, MAX_PATH); @@ -59,13 +59,15 @@ int CSkypeProto::StartSkypeRuntime(const wchar_t *profileName) PROCESSENTRY32 entry; entry.dwSize = sizeof(PROCESSENTRY32); + // todo: rework HANDLE snapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); - if (::Process32First(snapshot, &entry) == TRUE) { - while (::Process32Next(snapshot, &entry) == TRUE) { - if (::wcsicmp(entry.szExeFile, L"SkypeKit.exe") == 0) { - HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID); - this->runtimePort += rand() % 8963 + 1000; - ::CloseHandle(hProcess); + if (::Process32First(snapshot, &entry) == TRUE) + { + while (::Process32Next(snapshot, &entry) == TRUE) + { + if (::wcsicmp(entry.szExeFile, L"SkypeKit.exe") == 0) + { + this->skypeKitPort += rand() % 1000 + 8963; break; } } @@ -73,21 +75,21 @@ int CSkypeProto::StartSkypeRuntime(const wchar_t *profileName) ::CloseHandle(snapshot); wchar_t param[128]; - //PROCESS_INFORMATION pi; VARST dbPath( _T("%miranda_userdata%\\SkypeKit")); - ::swprintf(param, SIZEOF(param), L"-p -P %d -f \"%s\"", this->runtimePort, dbPath); + ::swprintf(param, SIZEOF(param), L"-p -P %d -f \"%s\"", this->skypeKitPort, dbPath); int startingrt = ::CreateProcess( fileName, param, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, - NULL, NULL, &cif, &this->pi); + NULL, NULL, &cif, &this->skypeKitProcessInfo); return startingrt; } void CSkypeProto::StopSkypeRuntime() { - DWORD exitCode = 0; - GetExitCodeProcess(this->pi.hProcess, &exitCode); - TerminateProcess(this->pi.hProcess, exitCode); + ::TerminateProcess(this->skypeKitProcessInfo.hProcess, 0); + ::CloseHandle(this->skypeKitProcessInfo.hThread); + ::CloseHandle(this->skypeKitProcessInfo.hProcess); + } \ No newline at end of file diff --git a/protocols/Skype/src/skype_transfers.cpp b/protocols/Skype/src/skype_transfers.cpp index 5f3270306a..13e1c1a5b3 100644 --- a/protocols/Skype/src/skype_transfers.cpp +++ b/protocols/Skype/src/skype_transfers.cpp @@ -89,7 +89,7 @@ void CSkypeProto::OnTransferChanged(CTransfer::Ref transfer, int prop) } } -void CSkypeProto::OnFile(const ConversationRef &conversation, const MessageRef &message) +void CSkypeProto::OnFileEvent(const ConversationRef &conversation, const MessageRef &message) { CTransfer::Refs transfers; message->GetTransfers(transfers); diff --git a/protocols/Skype/src/skype_utils.cpp b/protocols/Skype/src/skype_utils.cpp index 85a0a43a9b..69c99a37ec 100644 --- a/protocols/Skype/src/skype_utils.cpp +++ b/protocols/Skype/src/skype_utils.cpp @@ -374,7 +374,7 @@ void CSkypeProto::ShowNotification(const wchar_t *caption, const wchar_t *messag { POPUPDATAW ppd = {0}; ppd.lchContact = hContact; - //if (!hContact) + if ( !hContact) { ::wcsncpy(ppd.lpwzContactName, caption, MAX_CONTACTNAME); } -- cgit v1.2.3