From 27cac8c07ca2465c187bb90e7058a854f46b6746 Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Wed, 8 May 2013 15:08:27 +0000 Subject: - code restructurization - started network log filling git-svn-id: http://svn.miranda-ng.org/main/trunk@4598 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Skype/Skype_10.vcxproj | 3 + protocols/Skype/Skype_10.vcxproj.filters | 9 + protocols/Skype/src/skype_account.cpp | 29 ++- protocols/Skype/src/skype_chat.cpp | 41 ++++ protocols/Skype/src/skype_chat.h | 1 + protocols/Skype/src/skype_contacts.cpp | 2 + protocols/Skype/src/skype_events.cpp | 383 +++++-------------------------- protocols/Skype/src/skype_messages.cpp | 153 ++++++++++++ protocols/Skype/src/skype_profile.cpp | 3 +- protocols/Skype/src/skype_proto.cpp | 17 +- protocols/Skype/src/skype_proto.h | 26 +-- protocols/Skype/src/skype_transfers.cpp | 143 ++++++++++++ protocols/Skype/src/skype_utils.cpp | 17 ++ 13 files changed, 474 insertions(+), 353 deletions(-) create mode 100644 protocols/Skype/src/skype_chat.h create mode 100644 protocols/Skype/src/skype_messages.cpp create mode 100644 protocols/Skype/src/skype_transfers.cpp (limited to 'protocols/Skype') diff --git a/protocols/Skype/Skype_10.vcxproj b/protocols/Skype/Skype_10.vcxproj index 42a3ca8f67..1c508387ce 100644 --- a/protocols/Skype/Skype_10.vcxproj +++ b/protocols/Skype/Skype_10.vcxproj @@ -194,6 +194,7 @@ + @@ -223,10 +224,12 @@ + + diff --git a/protocols/Skype/Skype_10.vcxproj.filters b/protocols/Skype/Skype_10.vcxproj.filters index c080b72bef..9228cb9cd4 100644 --- a/protocols/Skype/Skype_10.vcxproj.filters +++ b/protocols/Skype/Skype_10.vcxproj.filters @@ -108,6 +108,12 @@ Source Files + + Source Files + + + Source Files + @@ -161,6 +167,9 @@ Header Files + + Header Files + diff --git a/protocols/Skype/src/skype_account.cpp b/protocols/Skype/src/skype_account.cpp index 3de83ee8dd..3202a6cec4 100644 --- a/protocols/Skype/src/skype_account.cpp +++ b/protocols/Skype/src/skype_account.cpp @@ -120,6 +120,7 @@ bool CSkypeProto::LogIn() this->SetAccountSettings(); + this->Log(L"Login in an account"); this->account->LoginWithPassword(this->password, false, false); } @@ -131,6 +132,7 @@ void CSkypeProto::LogOut() if (this->IsOnline() || this->m_iStatus == ID_STATUS_CONNECTING) { this->account->SetAvailability(CContact::OFFLINE); + this->Log(L"Logout from account"); this->account->Logout(true); this->SetAllContactStatus(ID_STATUS_OFFLINE); @@ -140,13 +142,19 @@ void CSkypeProto::LogOut() void CSkypeProto::SetAccountSettings() { int port = ::db_get_w(NULL, this->m_szModuleName, "Port", rand() % 10000 + 10000); + this->Log(L"Setting port number to %d", port); g_skype->SetInt(SETUPKEY_PORT, port); - g_skype->SetInt(SETUPKEY_DISABLE_PORT80, (int)!::db_get_b(NULL, this->m_szModuleName, "UseAlternativePorts", 1)); + + bool useAlternativePorts = (bool)::db_get_b(NULL, this->m_szModuleName, "UseAlternativePorts", 1); + if (useAlternativePorts) + this->Log(L"Setting listening of alternative ports (80, 443)"); + g_skype->SetInt(SETUPKEY_DISABLE_PORT80, (int)!useAlternativePorts); // Create default group for new contacts DBVARIANT dbv = {0}; - if (!::db_get_ts(NULL, m_szModuleName, SKYPE_SETTINGS_DEF_GROUP, &dbv) && lstrlen(dbv.ptszVal) > 0) + if ( !::db_get_ts(NULL, m_szModuleName, SKYPE_SETTINGS_DEF_GROUP, &dbv) && lstrlen(dbv.ptszVal) > 0) { + this->Log(L"Setting default group for new contacts"); ::CallService(MS_CLIST_GROUPCREATE, 0, (LPARAM)dbv.ptszVal); ::db_free(&dbv); } @@ -168,6 +176,7 @@ void CSkypeProto::InitProxy() { case PROXYTYPE_HTTP: case PROXYTYPE_HTTPS: + this->Log(L"Setting https user proxy config"); g_skype->SetInt(SETUPKEY_HTTPS_PROXY_ENABLE, 1); g_skype->SetInt(SETUPKEY_SOCKS_PROXY_ENABLE, 0); g_skype->SetStr(SETUPKEY_HTTPS_PROXY_ADDR, address); @@ -183,6 +192,7 @@ void CSkypeProto::InitProxy() case PROXYTYPE_SOCKS4: case PROXYTYPE_SOCKS5: + this->Log(L"Setting socks user proxy config"); g_skype->SetInt(SETUPKEY_HTTPS_PROXY_ENABLE, 0); g_skype->SetInt(SETUPKEY_SOCKS_PROXY_ENABLE, 1); g_skype->SetStr(SETUPKEY_SOCKS_PROXY_ADDR, address); @@ -194,6 +204,7 @@ void CSkypeProto::InitProxy() break; default: + this->Log(L"Setting automatic proxy detection"); g_skype->Delete(SETUPKEY_HTTPS_PROXY_ENABLE); g_skype->Delete(SETUPKEY_HTTPS_PROXY_ADDR); g_skype->Delete(SETUPKEY_HTTPS_PROXY_USER); @@ -220,14 +231,14 @@ void CSkypeProto::OnLoggedIn() ::CallService(MS_DB_CRYPT_ENCODESTRING, ::strlen(this->password), (LPARAM)this->password); } + this->SetServerStatus(this->m_iDesiredStatus); + this->LoadOwnInfo(this); this->LoadChatList(this); this->LoadContactList(reinterpret_cast(static_cast(true))); this->LoadAuthWaitList(this); fetch(this->transferList); - - this->SetServerStatus(this->m_iDesiredStatus); } void CSkypeProto::SetServerStatus(int iNewStatus) @@ -244,7 +255,10 @@ void CSkypeProto::SetServerStatus(int iNewStatus) CContact::AVAILABILITY availability = CSkypeProto::MirandaToSkypeStatus(iNewStatus); if (availability != CContact::UNKNOWN) + { + this->Log(L"Setting status to %d", iNewStatus); this->account->SetAvailability(availability); + } this->SendBroadcast(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldStatus, this->m_iStatus); } @@ -257,6 +271,8 @@ void CSkypeProto::OnCblUpdated() void CSkypeProto::OnLoggedOut(CAccount::LOGOUTREASON reason) { + this->Log(L"Failed to login: %s", CSkypeProto::SkypeToMirandaLoginError(reason)); + this->m_iStatus = ID_STATUS_OFFLINE; this->SendBroadcast( ACKTYPE_LOGIN, ACKRESULT_FAILED, @@ -292,7 +308,7 @@ void CSkypeProto::OnAccountChanged(int prop) if (loginStatus == CAccount::LOGGED_OUT) { CAccount::LOGOUTREASON reason; - if (!this->account->GetPropLogoutreason(reason)) + if ( !this->account->GetPropLogoutreason(reason)) break; if (reason != CAccount::LOGOUT_CALLED) @@ -318,7 +334,10 @@ void CSkypeProto::OnAccountChanged(int prop) CAccount::PWDCHANGESTATUS status; this->account->GetPropPwdchangestatus(status); if (status != CAccount::PWD_CHANGING) + { + this->Log(L"Failed to chage password: %s", CSkypeProto::PasswordChangeReasons[status]); this->ShowNotification(CSkypeProto::PasswordChangeReasons[status]); + } } break; diff --git a/protocols/Skype/src/skype_chat.cpp b/protocols/Skype/src/skype_chat.cpp index 4f73eda6a2..02a416dcaf 100644 --- a/protocols/Skype/src/skype_chat.cpp +++ b/protocols/Skype/src/skype_chat.cpp @@ -695,4 +695,45 @@ void CSkypeProto::UpdateChatUserStatus(CContact::Ref contact) 0, CSkypeProto::SkypeToMirandaStatus(availability)); } +} + +void CSkypeProto::OnChatMessageReceived(CConversation::Ref &conversation, CMessage::Ref &message) +{ + SEString data; + + uint timestamp; + message->GetPropTimestamp(timestamp); + + message->GetPropBodyXml(data); + char *text = CSkypeProto::RemoveHtml(data); + + message->GetPropAuthor(data); + mir_ptr sid( ::mir_utf8decodeW(data)); + + conversation->GetPropIdentity(data); + mir_ptr cid( ::mir_utf8decodeW(data)); + + //this->SendChatMessage(cid, sid, mir_ptr(::mir_utf8decodeW(text))); + this->RaiseChatEvent(cid, sid, GC_EVENT_MESSAGE, GCEF_ADDTOLOG, 0, NULL, mir_ptr(::mir_utf8decodeW(text))); +} + +void CSkypeProto::OnChatMessageSended(CConversation::Ref &conversation, CMessage::Ref &message) +{ + SEString data; + + uint timestamp; + message->GetPropTimestamp(timestamp); + + message->GetPropBodyXml(data); + char *text = CSkypeProto::RemoveHtml(data); + + conversation->GetPropIdentity(data); + mir_ptr cid( ::mir_utf8decodeW(data)); + + mir_ptr nick( ::db_get_wsa(NULL, this->m_szModuleName, "Nick")); + if (::wcsicmp(nick, L"") == 0) + nick = ::db_get_wsa(NULL, this->m_szModuleName, SKYPE_SETTINGS_LOGIN); + + //this->SendChatMessage(cid, nick, mir_ptr(::mir_utf8decodeW(text))); + this->RaiseChatEvent(cid, nick, GC_EVENT_MESSAGE, GCEF_ADDTOLOG, 0, NULL, mir_ptr(::mir_utf8decodeW(text))); } \ No newline at end of file diff --git a/protocols/Skype/src/skype_chat.h b/protocols/Skype/src/skype_chat.h new file mode 100644 index 0000000000..50e96676b7 --- /dev/null +++ b/protocols/Skype/src/skype_chat.h @@ -0,0 +1 @@ +#pragma once diff --git a/protocols/Skype/src/skype_contacts.cpp b/protocols/Skype/src/skype_contacts.cpp index aacbe82006..7c442ea5e6 100644 --- a/protocols/Skype/src/skype_contacts.cpp +++ b/protocols/Skype/src/skype_contacts.cpp @@ -246,6 +246,7 @@ HANDLE CSkypeProto::AddContact(CContact::Ref contact) void __cdecl CSkypeProto::LoadContactList(void* data) { + this->Log(L"Updating contacts list"); bool isFirstLoad = data != NULL; g_skype->GetHardwiredContactGroup(CContactGroup::ALL_BUDDIES, this->commonList); @@ -288,6 +289,7 @@ void __cdecl CSkypeProto::LoadContactList(void* data) void __cdecl CSkypeProto::LoadChatList(void*) { + this->Log(L"Updating group chats list"); CConversation::Refs conversations; g_skype->GetConversationList(conversations); diff --git a/protocols/Skype/src/skype_events.cpp b/protocols/Skype/src/skype_events.cpp index 6137de071d..ca54a4904d 100644 --- a/protocols/Skype/src/skype_events.cpp +++ b/protocols/Skype/src/skype_events.cpp @@ -30,7 +30,7 @@ int CSkypeProto::OnModulesLoaded(WPARAM, LPARAM) } g_skype->SetOnMessageCallback( - (CSkype::OnMessaged)&CSkypeProto::OnMessage, + (CSkype::OnMessaged)&CSkypeProto::OnSkypeEvent, this); return 0; @@ -42,6 +42,10 @@ int CSkypeProto::OnPreShutdown(WPARAM, LPARAM) { BBButton bbd = { sizeof(bbd) }; bbd.pszModuleName = MODULE; + + bbd.dwButtonID = BBB_ID_CONF_INVITE; + ::CallService(MS_BB_REMOVEBUTTON, 0, (LPARAM)&bbd); + bbd.dwButtonID = BBB_ID_CONF_SPAWN; ::CallService(MS_BB_REMOVEBUTTON, 0, (LPARAM)&bbd); } @@ -151,288 +155,7 @@ int __cdecl CSkypeProto::OnTabSRMMButtonPressed(WPARAM wParam, LPARAM lParam) return 1; } -int CSkypeProto::OnMessagePreCreate(WPARAM, LPARAM lParam) -{ - MessageWindowEvent *evt = (MessageWindowEvent *)lParam; - - MessageRef message(evt->seq); - SEBinary guid; - if (message->GetPropGuid(guid)) - { - char *cguid = ::mir_strdup(guid.data()); - cguid[guid.size()] = 0; - - evt->dbei->pBlob = (PBYTE)::mir_realloc(evt->dbei->pBlob, evt->dbei->cbBlob + guid.size()); - ::memcpy((char *)&evt->dbei->pBlob[evt->dbei->cbBlob], cguid, guid.size()); - evt->dbei->cbBlob += (DWORD)guid.size(); - } - - return 1; -} - -void CSkypeProto::OnMessageReceived(CConversation::Ref &conversation, CMessage::Ref &message) -{ - SEString data; - - CMessage::TYPE messageType; - message->GetPropType(messageType); - - uint timestamp; - message->GetPropTimestamp(timestamp); - - CMessage::CONSUMPTION_STATUS status; - message->GetPropConsumptionStatus(status); - - message->GetPropBodyXml(data); - char *text = CSkypeProto::RemoveHtml(data); - - CConversation::TYPE type; - conversation->GetPropType(type); - if (type == CConversation::DIALOG) - { - message->GetPropAuthor(data); - - CContact::Ref author; - g_skype->GetContact(data, author); - - HANDLE hContact = this->AddContact(author); - - SEBinary guid; - message->GetPropGuid(guid); - - char *cguid = ::mir_strdup(guid.data()); - cguid[guid.size()] = 0; - - this->RaiseMessageReceivedEvent( - hContact, - timestamp, - cguid, - text, - status == CMessage::UNCONSUMED_NORMAL); - } - else - { - message->GetPropAuthor(data); - mir_ptr sid( ::mir_utf8decodeW(data)); - - conversation->GetPropIdentity(data); - mir_ptr cid( ::mir_utf8decodeW(data)); - - this->SendChatMessage(cid, sid, mir_ptr(::mir_utf8decodeW(text))); - } -} - -void CSkypeProto::OnMessageSended(CConversation::Ref &conversation, CMessage::Ref &message) -{ - SEString data; - - CMessage::TYPE messageType; - message->GetPropType(messageType); - - uint timestamp; - message->GetPropTimestamp(timestamp); - - CMessage::SENDING_STATUS sstatus; - message->GetPropSendingStatus(sstatus); - - CMessage::CONSUMPTION_STATUS status; - message->GetPropConsumptionStatus(status); - - message->GetPropBodyXml(data); - char *text = CSkypeProto::RemoveHtml(data); - - CConversation::TYPE type; - conversation->GetPropType(type); - if (type == CConversation::DIALOG) - { - CParticipant::Refs participants; - conversation->GetParticipants(participants, CConversation::OTHER_CONSUMERS); - participants[0]->GetPropIdentity(data); - - CContact::Ref receiver; - g_skype->GetContact(data, receiver); - - HANDLE hContact = this->AddContact(receiver); - - //if (sstatus != CMessage::SENDING) - { - this->SendBroadcast( - hContact, - ACKTYPE_MESSAGE, - sstatus == CMessage::FAILED_TO_SEND ? ACKRESULT_FAILED : ACKRESULT_SUCCESS, - (HANDLE)message->getOID(), 0); - - SEBinary guid; - message->GetPropGuid(guid); - - char *cguid = ::mir_strdup(guid.data()); - cguid[guid.size()] = 0; - - this->RaiseMessageSendedEvent( - hContact, - timestamp, - cguid, - text, - status == CMessage::UNCONSUMED_NORMAL); - } - } - else - { - conversation->GetPropIdentity(data); - mir_ptr cid( ::mir_utf8decodeW(data)); - - mir_ptr nick( ::db_get_wsa(NULL, this->m_szModuleName, "Nick")); - if (::wcsicmp(nick, L"") == 0) - nick = ::db_get_wsa(NULL, this->m_szModuleName, SKYPE_SETTINGS_LOGIN); - - this->SendChatMessage(cid, nick, mir_ptr(::mir_utf8decodeW(text))); - } -} - - -void CSkypeProto::OnTransferChanged(CTransfer::Ref transfer, int prop) -{ - switch (prop) - { - case Transfer::P_STATUS: - { - SEBinary guid; - transfer->GetPropChatmsgGuid(guid); - - CMessage::Ref message; - g_skype->GetMessageByGuid(guid, message); - - uint oid = message->getOID(); - - SEString data; - transfer->GetPropPartnerHandle(data); - HANDLE hContact = this->GetContactBySid(mir_ptr(::mir_utf8decodeW(data))); - - Transfer::STATUS status; - transfer->GetPropStatus(status); - switch(status) - { - /*case CTransfer::NEW: - break;*/ - /*case CTransfer::WAITING_FOR_ACCEPT: - break;*/ - case CTransfer::CONNECTING: - this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, (HANDLE)oid, 0); - break; - case CTransfer::TRANSFERRING: - case CTransfer::TRANSFERRING_OVER_RELAY: - this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)oid, 0); - break; - case CTransfer::FAILED: - this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)oid, 0); - this->transferList.remove_val(transfer); - break; - case CTransfer::COMPLETED: - this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, (HANDLE)oid, 0); - this->transferList.remove_val(transfer); - break; - case CTransfer::CANCELLED: - case CTransfer::CANCELLED_BY_REMOTE: - this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)oid, 0); - this->transferList.remove_val(transfer); - break; - } - } - break; - - case Transfer::P_BYTESTRANSFERRED: - { - SEString data; - - SEBinary guid; - transfer->GetPropChatmsgGuid(guid); - - CMessage::Ref message; - g_skype->GetMessageByGuid(guid, message); - - uint oid = message->getOID(); - - PROTOFILETRANSFERSTATUS pfts = {0}; - pfts.cbSize = sizeof(pfts); - pfts.flags = PFTS_UTF | PFTS_RECEIVING; - pfts.totalFiles = 1; - pfts.currentFileNumber = 0; - - transfer->GetPropPartnerHandle(data); - HANDLE hContact = this->GetContactBySid(mir_ptr(::mir_utf8decodeW(data))); - pfts.hContact = hContact; - - transfer->GetPropFilename(data); - pfts.szCurrentFile = ::mir_strdup(data); - - pfts.pszFiles = &pfts.szCurrentFile; - - transfer->GetPropFilesize(data); - pfts.totalBytes = pfts.currentFileSize = data.toUInt64(); - - transfer->GetPropBytestransferred(data); - pfts.totalProgress = pfts.currentFileProgress = data.toUInt64(); - - this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)oid, (LPARAM)&pfts); - } - break; - } -} - -void CSkypeProto::OnFile(CConversation::Ref &conversation, CMessage::Ref &message) -{ - CTransfer::Refs transfers; - message->GetTransfers(transfers); - //Sid::fetch(transferList); - - Transfer::TYPE transferType; - Transfer::STATUS transferStatus; - - for (uint i = 0; i < transfers.size(); i++) - { - auto transfer = transfers[i]; - - // For incomings, we need to check for transfer status, just to be sure. - // In some cases, a transfer can appear with STATUS == PLACEHOLDER - // As such transfers cannot be accepted, we will need to just store - // the reference to Transfer Object and then check for further - // status changes in Transfer::OnChange - transfer->GetPropStatus(transferStatus); - if (transferStatus == Transfer::NEW) - { - transfer->GetPropType(transferType); - if (transferType == Transfer::INCOMING) - { - transfer.fetch(); - transfer->SetOnTransferCallback( - (CTransfer::OnTransfer)&CSkypeProto::OnTransferChanged, - this); - this->transferList.append(transfer); - - uint timestamp; - message->GetPropTimestamp(timestamp); - - SEString data; - transfer->GetPropPartnerHandle(data); - HANDLE hContact = this->GetContactBySid(mir_ptr(::mir_utf8decodeW(data))); - - transfer->GetPropFilename(data); - wchar_t *path = ::mir_utf8decodeW(data); - - PROTORECVFILET pre = {0}; - pre.flags = PREF_TCHAR; - pre.fileCount = 1; - pre.timestamp = timestamp; - pre.tszDescription = L" "; - pre.ptszFiles = &path; - pre.lParam = (LPARAM)message->getOID(); - ::ProtoChainRecvFile(hContact, &pre); - } - } - } -} - -void CSkypeProto::OnMessage(CConversation::Ref conversation, CMessage::Ref message) +void CSkypeProto::OnChatEvent(CConversation::Ref &conversation, CMessage::Ref &message) { CMessage::TYPE messageType; message->GetPropType(messageType); @@ -446,16 +169,12 @@ void CSkypeProto::OnMessage(CConversation::Ref conversation, CMessage::Ref messa message->GetPropAuthor(author); if (::wcsicmp(mir_ptr(::mir_utf8decodeW(author)), this->login) == 0) - this->OnMessageSended(conversation, message); + this->OnChatMessageSended(conversation, message); else - this->OnMessageReceived(conversation, message); + this->OnChatMessageReceived(conversation, message); } break; - case CMessage::POSTED_FILES: - this->OnFile(conversation, message); - break; - case CMessage::ADDED_CONSUMERS: { SEString data; @@ -520,6 +239,7 @@ void CSkypeProto::OnMessage(CConversation::Ref conversation, CMessage::Ref messa this->RemoveChatContact(cid, sid); } break; + case CMessage::RETIRED_OTHERS: { SEString data; @@ -562,58 +282,79 @@ void CSkypeProto::OnMessage(CConversation::Ref conversation, CMessage::Ref messa break; case CMessage::STARTED_LIVESESSION: - conversation->LeaveLiveSession(); - - CConversation::TYPE type; - conversation->GetPropType(type); - if (type == CConversation::DIALOG) { + conversation->LeaveLiveSession(); - uint timestamp; - message->GetPropTimestamp(timestamp); - - SEString identity; - message->GetPropAuthor(identity); - - CContact::Ref author; - g_skype->GetContact(identity, author); - - HANDLE hContact = this->AddContact(author); - - char *message = ::mir_utf8encode(::Translate("Incoming call")); - - this->AddDBEvent( - hContact, - SKYPE_DB_EVENT_TYPE_CALL, - timestamp, - DBEF_UTF, - (DWORD)::strlen(message) + 1, - (PBYTE)message); - } - else - { SEString data; conversation->GetPropIdentity(data); mir_ptr cid( ::mir_utf8decodeW(data)); HANDLE hContact = this->GetChatRoomByCid(cid); - this->RaiseChatEvent(cid, this->login, /*GC_EVENT_INFORMATION*/ 0x0100, /*GCEF_ADDTOLOG*/ 0x0001, 0, NULL, ::TranslateT("Group call")); + + this->RaiseChatEvent( + cid, + this->login, + /*GC_EVENT_INFORMATION*/ 0x0100, + /*GCEF_ADDTOLOG*/ 0x0001, + 0, + NULL, + ::TranslateT("Group call")); } break; case CMessage::ENDED_LIVESESSION: - conversation->GetPropType(type); - if (type != CConversation::DIALOG) { SEString data; conversation->GetPropIdentity(data); mir_ptr cid( ::mir_utf8decodeW(data)); HANDLE hContact = this->GetChatRoomByCid(cid); - this->RaiseChatEvent(cid, this->login, /*GC_EVENT_INFORMATION*/ 0x0100, /*GCEF_ADDTOLOG*/ 0x0001, 0, NULL, ::TranslateT("The call is completed")); + + this->RaiseChatEvent( + cid, + this->login, + /*GC_EVENT_INFORMATION*/ 0x0100, + /*GCEF_ADDTOLOG*/ 0x0001, + 0, + NULL, + ::TranslateT("The call is completed")); + } + break; + } +} + +void CSkypeProto::OnSkypeEvent(CConversation::Ref conversation, CMessage::Ref message) +{ + CMessage::TYPE messageType; + message->GetPropType(messageType); + + switch (messageType) + { + case CMessage::POSTED_EMOTE: + case CMessage::POSTED_TEXT: + case CMessage::STARTED_LIVESESSION: + case CMessage::ENDED_LIVESESSION: + { + CConversation::TYPE type; + conversation->GetPropType(type); + if (type == CConversation::DIALOG) + this->OnMessageEvent(conversation, message); + else + this->OnChatEvent(conversation, message); } break; + case CMessage::ADDED_CONSUMERS: + case CMessage::RETIRED: + case CMessage::RETIRED_OTHERS: + case CMessage::SPAWNED_CONFERENCE: + this->OnChatEvent(conversation, message); + break; + + case CMessage::POSTED_FILES: + this->OnFile(conversation, message); + break; + //case CMessage::REQUESTED_AUTH: // break; diff --git a/protocols/Skype/src/skype_messages.cpp b/protocols/Skype/src/skype_messages.cpp new file mode 100644 index 0000000000..31d08c19f9 --- /dev/null +++ b/protocols/Skype/src/skype_messages.cpp @@ -0,0 +1,153 @@ +#include "skype_proto.h" + +int CSkypeProto::OnMessagePreCreate(WPARAM, LPARAM lParam) +{ + MessageWindowEvent *evt = (MessageWindowEvent *)lParam; + + MessageRef message(evt->seq); + SEBinary guid; + if (message->GetPropGuid(guid)) + { + char *cguid = ::mir_strdup(guid.data()); + cguid[guid.size()] = 0; + + evt->dbei->pBlob = (PBYTE)::mir_realloc(evt->dbei->pBlob, evt->dbei->cbBlob + guid.size()); + ::memcpy((char *)&evt->dbei->pBlob[evt->dbei->cbBlob], cguid, guid.size()); + evt->dbei->cbBlob += (DWORD)guid.size(); + } + + return 1; +} + +void CSkypeProto::OnMessageReceived(CConversation::Ref &conversation, CMessage::Ref &message) +{ + SEString data; + + CMessage::TYPE messageType; + message->GetPropType(messageType); + + uint timestamp; + message->GetPropTimestamp(timestamp); + + CMessage::CONSUMPTION_STATUS status; + message->GetPropConsumptionStatus(status); + + message->GetPropBodyXml(data); + char *text = CSkypeProto::RemoveHtml(data); + + message->GetPropAuthor(data); + + CContact::Ref author; + g_skype->GetContact(data, author); + + HANDLE hContact = this->AddContact(author); + + SEBinary guid; + message->GetPropGuid(guid); + + char *cguid = ::mir_strdup(guid.data()); + cguid[guid.size()] = 0; + + this->RaiseMessageReceivedEvent( + hContact, + timestamp, + cguid, + text, + status == CMessage::UNCONSUMED_NORMAL); +} + +void CSkypeProto::OnMessageSended(CConversation::Ref &conversation, CMessage::Ref &message) +{ + SEString data; + + CMessage::TYPE messageType; + message->GetPropType(messageType); + + uint timestamp; + message->GetPropTimestamp(timestamp); + + CMessage::SENDING_STATUS sstatus; + message->GetPropSendingStatus(sstatus); + + CMessage::CONSUMPTION_STATUS status; + message->GetPropConsumptionStatus(status); + + message->GetPropBodyXml(data); + char *text = CSkypeProto::RemoveHtml(data); + + CParticipant::Refs participants; + conversation->GetParticipants(participants, CConversation::OTHER_CONSUMERS); + participants[0]->GetPropIdentity(data); + + CContact::Ref receiver; + g_skype->GetContact(data, receiver); + + HANDLE hContact = this->AddContact(receiver); + + this->SendBroadcast( + hContact, + ACKTYPE_MESSAGE, + sstatus == CMessage::FAILED_TO_SEND ? ACKRESULT_FAILED : ACKRESULT_SUCCESS, + (HANDLE)message->getOID(), 0); + + SEBinary guid; + message->GetPropGuid(guid); + + char *cguid = ::mir_strdup(guid.data()); + cguid[guid.size()] = 0; + + this->RaiseMessageSendedEvent( + hContact, + timestamp, + cguid, + text, + status == CMessage::UNCONSUMED_NORMAL); +} + +void CSkypeProto::OnMessageEvent(CConversation::Ref conversation, CMessage::Ref message) +{ + CMessage::TYPE messageType; + message->GetPropType(messageType); + + switch (messageType) + { + case CMessage::POSTED_EMOTE: + case CMessage::POSTED_TEXT: + { + SEString author; + message->GetPropAuthor(author); + + if (::wcsicmp(mir_ptr(::mir_utf8decodeW(author)), this->login) == 0) + this->OnMessageSended(conversation, message); + else + this->OnMessageReceived(conversation, message); + } + break; + + case CMessage::STARTED_LIVESESSION: + { + conversation->LeaveLiveSession(); + + uint timestamp; + message->GetPropTimestamp(timestamp); + + SEString identity; + message->GetPropAuthor(identity); + + CContact::Ref author; + g_skype->GetContact(identity, author); + + HANDLE hContact = this->AddContact(author); + + char *message = ::mir_utf8encode(::Translate("Incoming call")); + + this->AddDBEvent( + hContact, + SKYPE_DB_EVENT_TYPE_CALL, + timestamp, + DBEF_UTF, + (DWORD)::strlen(message) + 1, + (PBYTE)message); + } + } +} \ No newline at end of file diff --git a/protocols/Skype/src/skype_profile.cpp b/protocols/Skype/src/skype_profile.cpp index 3e9a1c2e20..8448475817 100644 --- a/protocols/Skype/src/skype_profile.cpp +++ b/protocols/Skype/src/skype_profile.cpp @@ -275,6 +275,7 @@ void CSkypeProto::UpdateProfileTimezone(SEObject *obj, HANDLE hContact) void CSkypeProto::UpdateProfile(SEObject *obj, HANDLE hContact) { + this->Log(L"Updating profile for %p", hContact); this->UpdateProfileAvatar(obj, hContact); uint newTS = hContact ? obj->GetUintProp(Contact::P_PROFILE_TIMESTAMP) : obj->GetUintProp(Account::P_PROFILE_TIMESTAMP); @@ -320,6 +321,6 @@ void __cdecl CSkypeProto::LoadOwnInfo(void *) nick = ::mir_utf8decodeW(data); ::db_set_ws(NULL, this->m_szModuleName, "Nick", nick); } - this->UpdateProfileAvatar(this->account.fetch()); + //this->UpdateProfileAvatar(this->account.fetch()); this->UpdateProfile(this->account.fetch()); } \ No newline at end of file diff --git a/protocols/Skype/src/skype_proto.cpp b/protocols/Skype/src/skype_proto.cpp index 2a92a7ea5e..a8b1c0a315 100644 --- a/protocols/Skype/src/skype_proto.cpp +++ b/protocols/Skype/src/skype_proto.cpp @@ -38,11 +38,9 @@ CSkypeProto::~CSkypeProto() HANDLE __cdecl CSkypeProto::AddToList(int flags, PROTOSEARCHRESULT* psr) { - //fixme CContact::Ref contact; - g_skype->GetContact(::mir_u2a(psr->id), contact); + g_skype->GetContact((char *)mir_ptr(::mir_utf8encodeW(psr->id)), contact); return this->AddContact(contact); - return 0; } HANDLE __cdecl CSkypeProto::AddToListByEvent(int flags, int iContact, HANDLE hDbEvent) @@ -142,6 +140,7 @@ HANDLE __cdecl CSkypeProto::FileAllow( HANDLE hContact, HANDLE hTransfer, const CMessage *message = new CMessage(oid, g_skype); + this->Log(L"Incoming file transfer is accepted"); CTransfer::Refs transfers; message->GetTransfers(transfers); for (uint i = 0; i < transfers.size(); i++) @@ -153,7 +152,6 @@ HANDLE __cdecl CSkypeProto::FileAllow( HANDLE hContact, HANDLE hTransfer, const ::mir_sntprintf(fullPath, MAX_PATH, L"%s%s", szPath, ::mir_utf8decodeW(name)); if (!transfers[i]->Accept(::mir_u2a(fullPath), success) || !success) { - // todo: write to log! delete message; return 0; } @@ -170,13 +168,13 @@ int __cdecl CSkypeProto::FileCancel( HANDLE hContact, HANDLE hTransfer ) MessageRef message(oid); + this->Log(L"Incoming file transfer is cancelled"); CTransfer::Refs transfers; message->GetTransfers(transfers); for (uint i = 0; i < transfers.size(); i++) { if (!transfers[i]->Cancel()) { - // todo: write to log! return 0; } } @@ -189,14 +187,13 @@ int __cdecl CSkypeProto::FileDeny( HANDLE hContact, HANDLE hTransfer, const T uint oid = (uint)hTransfer; MessageRef message(oid); - + this->Log(L"Incoming file transfer is denied"); CTransfer::Refs transfers; message->GetTransfers(transfers); for (uint i = 0; i < transfers.size(); i++) { if (!transfers[i]->Cancel()) { - // todo: write to log! return 0; } } @@ -222,7 +219,7 @@ DWORD_PTR __cdecl CSkypeProto:: GetCaps(int type, HANDLE hContact) return PF4_FORCEAUTH | PF4_FORCEADDED | PF4_SUPPORTTYPING | PF4_AVATARS | PF4_OFFLINEFILES | PF4_IMSENDUTF | PF4_IMSENDOFFLINE; case PFLAG_UNIQUEIDTEXT: - return (DWORD_PTR)::Translate("g_skype Name"); + return (DWORD_PTR)::Translate("Skype Name"); case PFLAG_UNIQUEIDSETTING: return (DWORD_PTR)SKYPE_SETTINGS_LOGIN; default: @@ -274,12 +271,14 @@ int __cdecl CSkypeProto::RecvContacts( HANDLE hContact, PROTORECVEVENT* ) { r int __cdecl CSkypeProto::RecvFile( HANDLE hContact, PROTORECVFILET* evt) { + this->Log(L"Incoming file transfer"); ::db_unset(hContact, "CList", "Hidden"); return ::Proto_RecvFile(hContact, evt); } int __cdecl CSkypeProto::RecvMsg(HANDLE hContact, PROTORECVEVENT* pre) { + this->Log(L"Incoming message"); ::db_unset(hContact, "CList", "Hidden"); this->UserIsTyping(hContact, PROTOTYPE_SELFTYPING_OFF); @@ -311,6 +310,7 @@ HANDLE __cdecl CSkypeProto::SendFile(HANDLE hContact, const TCHAR *szDescription { if (this->IsOnline() && hContact && ppszFiles) { + this->Log(L"Outcoming file transfer"); SEStringList targets; mir_ptr sid(::db_get_wsa(hContact, this->m_szModuleName, SKYPE_SETTINGS_LOGIN)); targets.append((char *)mir_ptr(::mir_utf8encodeW(sid))); @@ -348,6 +348,7 @@ HANDLE __cdecl CSkypeProto::SendFile(HANDLE hContact, const TCHAR *szDescription int __cdecl CSkypeProto::SendMsg(HANDLE hContact, int flags, const char *msg) { + this->Log(L"Outcoming message"); SEStringList targets; mir_ptr sid( ::db_get_wsa(hContact, this->m_szModuleName, SKYPE_SETTINGS_LOGIN)); SEString identity = ::mir_u2a(sid); diff --git a/protocols/Skype/src/skype_proto.h b/protocols/Skype/src/skype_proto.h index 1326eda358..2076d12901 100644 --- a/protocols/Skype/src/skype_proto.h +++ b/protocols/Skype/src/skype_proto.h @@ -20,23 +20,6 @@ struct _tag_iconList HANDLE Handle; }; -struct HtmlEntity -{ - const char *entity; - char symbol; -}; - -const HtmlEntity htmlEntities[]={ - {"nbsp", ' '}, - {"amp", '&'}, - {"quot", '"'}, - {"lt", '<'}, - {"gt", '>'}, - {"apos", '\''}, - {"copy", '©'}, - // TODO: add more -}; - struct InviteChatParam { wchar_t *id; @@ -242,8 +225,12 @@ protected: SEBinary GetAvatarBinary(wchar_t *path); + // events + void OnSkypeEvent(CConversation::Ref conversation, CMessage::Ref message); + void OnChatEvent(CConversation::Ref &conversation, CMessage::Ref &message); + // messages - void OnMessage(CConversation::Ref conversation, CMessage::Ref message); + void OnMessageEvent(CConversation::Ref conversation, CMessage::Ref message); void OnMessageSended(CConversation::Ref &conversation, CMessage::Ref &message); void OnMessageReceived(CConversation::Ref &conversation, CMessage::Ref &message); @@ -288,6 +275,9 @@ protected: int __cdecl OnGCMenuHook(WPARAM, LPARAM lParam); int __cdecl OnGCEventHook(WPARAM, LPARAM lParam); + + void OnChatMessageSended(CConversation::Ref &conversation, CMessage::Ref &message); + void OnChatMessageReceived(CConversation::Ref &conversation, CMessage::Ref &message); // contacts void UpdateContactAuthState(HANDLE hContact, CContact::Ref contact); diff --git a/protocols/Skype/src/skype_transfers.cpp b/protocols/Skype/src/skype_transfers.cpp new file mode 100644 index 0000000000..3fd10a14fc --- /dev/null +++ b/protocols/Skype/src/skype_transfers.cpp @@ -0,0 +1,143 @@ +#include "skype_proto.h" + +void CSkypeProto::OnTransferChanged(CTransfer::Ref transfer, int prop) +{ + switch (prop) + { + case Transfer::P_STATUS: + { + SEBinary guid; + transfer->GetPropChatmsgGuid(guid); + + CMessage::Ref message; + g_skype->GetMessageByGuid(guid, message); + + uint oid = message->getOID(); + + SEString data; + transfer->GetPropPartnerHandle(data); + HANDLE hContact = this->GetContactBySid(mir_ptr(::mir_utf8decodeW(data))); + + Transfer::STATUS status; + transfer->GetPropStatus(status); + switch(status) + { + /*case CTransfer::NEW: + break;*/ + /*case CTransfer::WAITING_FOR_ACCEPT: + break;*/ + case CTransfer::CONNECTING: + this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, (HANDLE)oid, 0); + break; + case CTransfer::TRANSFERRING: + case CTransfer::TRANSFERRING_OVER_RELAY: + this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)oid, 0); + break; + case CTransfer::FAILED: + this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)oid, 0); + this->transferList.remove_val(transfer); + break; + case CTransfer::COMPLETED: + this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, (HANDLE)oid, 0); + this->transferList.remove_val(transfer); + break; + case CTransfer::CANCELLED: + case CTransfer::CANCELLED_BY_REMOTE: + this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)oid, 0); + this->transferList.remove_val(transfer); + break; + } + } + break; + + case Transfer::P_BYTESTRANSFERRED: + { + SEString data; + + SEBinary guid; + transfer->GetPropChatmsgGuid(guid); + + CMessage::Ref message; + g_skype->GetMessageByGuid(guid, message); + + uint oid = message->getOID(); + + PROTOFILETRANSFERSTATUS pfts = {0}; + pfts.cbSize = sizeof(pfts); + pfts.flags = PFTS_UTF | PFTS_RECEIVING; + pfts.totalFiles = 1; + pfts.currentFileNumber = 0; + + transfer->GetPropPartnerHandle(data); + HANDLE hContact = this->GetContactBySid(mir_ptr(::mir_utf8decodeW(data))); + pfts.hContact = hContact; + + transfer->GetPropFilename(data); + pfts.szCurrentFile = ::mir_strdup(data); + + pfts.pszFiles = &pfts.szCurrentFile; + + transfer->GetPropFilesize(data); + pfts.totalBytes = pfts.currentFileSize = data.toUInt64(); + + transfer->GetPropBytestransferred(data); + pfts.totalProgress = pfts.currentFileProgress = data.toUInt64(); + + this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)oid, (LPARAM)&pfts); + } + break; + } +} + +void CSkypeProto::OnFile(CConversation::Ref &conversation, CMessage::Ref &message) +{ + CTransfer::Refs transfers; + message->GetTransfers(transfers); + //Sid::fetch(transferList); + + Transfer::TYPE transferType; + Transfer::STATUS transferStatus; + + for (uint i = 0; i < transfers.size(); i++) + { + auto transfer = transfers[i]; + + // For incomings, we need to check for transfer status, just to be sure. + // In some cases, a transfer can appear with STATUS == PLACEHOLDER + // As such transfers cannot be accepted, we will need to just store + // the reference to Transfer Object and then check for further + // status changes in Transfer::OnChange + transfer->GetPropStatus(transferStatus); + if (transferStatus == Transfer::NEW) + { + transfer->GetPropType(transferType); + if (transferType == Transfer::INCOMING) + { + transfer.fetch(); + transfer->SetOnTransferCallback( + (CTransfer::OnTransfer)&CSkypeProto::OnTransferChanged, + this); + this->transferList.append(transfer); + + uint timestamp; + message->GetPropTimestamp(timestamp); + + SEString data; + transfer->GetPropPartnerHandle(data); + HANDLE hContact = this->GetContactBySid(mir_ptr(::mir_utf8decodeW(data))); + + transfer->GetPropFilename(data); + wchar_t *path = ::mir_utf8decodeW(data); + + PROTORECVFILET pre = {0}; + pre.flags = PREF_TCHAR; + pre.fileCount = 1; + pre.timestamp = timestamp; + pre.tszDescription = L" "; + pre.ptszFiles = &path; + pre.lParam = (LPARAM)message->getOID(); + ::ProtoChainRecvFile(hContact, &pre); + } + } + } +} \ No newline at end of file diff --git a/protocols/Skype/src/skype_utils.cpp b/protocols/Skype/src/skype_utils.cpp index 26421f7e03..2bfbb2319f 100644 --- a/protocols/Skype/src/skype_utils.cpp +++ b/protocols/Skype/src/skype_utils.cpp @@ -389,6 +389,23 @@ void CSkypeProto::ShowNotification(const wchar_t *message, int flags, HANDLE hCo CSkypeProto::ShowNotification(::TranslateT(MODULE), message, flags, hContact); } +struct HtmlEntity +{ + const char *entity; + char symbol; +}; + +const HtmlEntity htmlEntities[]={ + {"nbsp", ' '}, + {"amp", '&'}, + {"quot", '"'}, + {"lt", '<'}, + {"gt", '>'}, + {"apos", '\''}, + {"copy", '©'}, + // TODO: add more +}; + char *CSkypeProto::RemoveHtml(const char *text) { std::string new_string = ""; -- cgit v1.2.3