From 5bc3f5153749a79e195e7e15ebe4d80ea3ddfa8e Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Sat, 17 Aug 2013 18:50:20 +0000 Subject: Skype: some changes in file transfer git-svn-id: http://svn.miranda-ng.org/main/trunk@5732 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Skype/src/skype_chat.cpp | 5 +- protocols/Skype/src/skype_dialogs.cpp | 8 +- protocols/Skype/src/skype_proto.cpp | 221 +++++++++++++++++++------------ protocols/Skype/src/skype_proto.h | 43 ++++++ protocols/Skype/src/skype_transfers.cpp | 168 ++++++++++++----------- protocols/Skype/src/skypekit/contact.cpp | 8 +- 6 files changed, 277 insertions(+), 176 deletions(-) (limited to 'protocols/Skype/src') diff --git a/protocols/Skype/src/skype_chat.cpp b/protocols/Skype/src/skype_chat.cpp index ee3626842e..e24b075645 100644 --- a/protocols/Skype/src/skype_chat.cpp +++ b/protocols/Skype/src/skype_chat.cpp @@ -1565,10 +1565,7 @@ void CSkypeProto::UpdateChatUserNick(const ContactRef &contact) contact->GetIdentity(data); ptrW sid(::mir_utf8decodeW(data)); - contact->GetPropFullname(data); - ptrW nick(::mir_utf8decodeW(data)); - if (data.length() == 0) - nick = ::mir_wstrdup(sid); + ptrW nick(::mir_utf8decodeW(((CContact::Ref)contact)->GetNick())); GC_INFO gci = {0}; gci.Flags = BYINDEX | DATA; diff --git a/protocols/Skype/src/skype_dialogs.cpp b/protocols/Skype/src/skype_dialogs.cpp index f907eedb90..88d0254bcc 100644 --- a/protocols/Skype/src/skype_dialogs.cpp +++ b/protocols/Skype/src/skype_dialogs.cpp @@ -203,13 +203,13 @@ INT_PTR CALLBACK CSkypeProto::SkypePrivacyOptionsProc(HWND hwndDlg, UINT msg, WP } break; - case WM_COMMAND: + /*case WM_COMMAND: { switch(LOWORD(wParam)) { } } - break; + break;*/ case WM_NOTIFY: if (reinterpret_cast(lParam)->code == PSN_APPLY && !ppro->IsOnline()) @@ -218,10 +218,10 @@ INT_PTR CALLBACK CSkypeProto::SkypePrivacyOptionsProc(HWND hwndDlg, UINT msg, WP } break; - switch(LOWORD(wParam)) + /*switch(LOWORD(wParam)) { } - break; + break;*/ } return FALSE; } diff --git a/protocols/Skype/src/skype_proto.cpp b/protocols/Skype/src/skype_proto.cpp index b4890011ef..8d0017d2a3 100644 --- a/protocols/Skype/src/skype_proto.cpp +++ b/protocols/Skype/src/skype_proto.cpp @@ -16,7 +16,7 @@ CSkypeProto::CSkypeProto(const char* protoName, const TCHAR* userName) : DBEVENTTYPEDESCR dbEventType = { sizeof(dbEventType) }; dbEventType.module = this->m_szModuleName; dbEventType.flags = DETF_HISTORY | DETF_MSGWINDOW; - + dbEventType.eventType = SKYPE_DB_EVENT_TYPE_EMOTE; dbEventType.descr = "Skype emote"; ::CallService(MS_DB_EVENT_REGISTERTYPE, 0, (LPARAM)&dbEventType); @@ -62,17 +62,17 @@ HANDLE __cdecl CSkypeProto::AddToListByEvent(int flags, int iContact, HANDLE hDb /*if ((dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0)) != -1) { - dbei.pBlob = (PBYTE)alloca(dbei.cbBlob); - if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei) == 0 && - !strcmp(dbei.szModule, m_szModuleName) && - (dbei.eventType == EVENTTYPE_AUTHREQUEST || dbei.eventType == EVENTTYPE_CONTACTS)) - { - char *nick = (char*)(dbei.pBlob + sizeof(DWORD) * 2); - char *firstName = nick + strlen(nick) + 1; - char *lastName = firstName + strlen(firstName) + 1; - char *skypeName = lastName + strlen(lastName) + 1; - return AddContactBySkypeName(::mir_a2u(skypeName), ::mir_a2u(nick), 0); - } + dbei.pBlob = (PBYTE)alloca(dbei.cbBlob); + if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei) == 0 && + !strcmp(dbei.szModule, m_szModuleName) && + (dbei.eventType == EVENTTYPE_AUTHREQUEST || dbei.eventType == EVENTTYPE_CONTACTS)) + { + char *nick = (char*)(dbei.pBlob + sizeof(DWORD) * 2); + char *firstName = nick + strlen(nick) + 1; + char *lastName = firstName + strlen(firstName) + 1; + char *skypeName = lastName + strlen(lastName) + 1; + return AddContactBySkypeName(::mir_a2u(skypeName), ::mir_a2u(nick), 0); + } }*/ return 0; } @@ -156,36 +156,40 @@ HANDLE __cdecl CSkypeProto::FileAllow( HANDLE hContact, HANDLE hTransfer, const wchar_t fullPath[MAX_PATH] = {0}; SEString data; - TransferRef transfer(oid); - //TransferRefs transfers; - //msgRef->GetTransfers(transfers); - //for (uint i = 0; i < transfers.size(); i++) + MessageRef msgRef(oid); + TransferRefs transfers; + msgRef->GetTransfers(transfers); + for (uint i = 0; i < transfers.size(); i++) { + auto transfer = transfers[i]; transfer->GetPropFilename(data); ptrW name(::mir_utf8decodeW(data)); ::mir_sntprintf(fullPath, MAX_PATH, L"%s%s", szPath, name); - //PROTOFILETRANSFERSTATUS pfts = {0}; - //ZeroMemory(&pfts, sizeof(PROTOFILETRANSFERSTATUS)); - //pfts.cbSize = sizeof(PROTOFILETRANSFERSTATUS); + auto fOid = transfer->getOID(); + FileTransferParam ftp = this->transferts[oid]; + + //PROTOFILETRANSFERSTATUS pfts = { sizeof(pfts) }; //pfts.hContact = hContact; - //pfts.flags = PFTS_TCHAR | PFTS_RECEIVING; /* Standard FT is Ansi only */ - //pfts.pszFiles = NULL; /* FIXME */ - //pfts.totalFiles = transfers.size(); + //pfts.flags = PFTS_UNICODE | PFTS_RECEIVING; + //pfts.ptszFiles = ftp.pfts.ptszFiles; + //pfts.totalFiles = ftp.pfts.totalFiles; //pfts.currentFileNumber = i; - ////pfts.totalBytes = transfers[i]->GetUintProp(Transfer::P_FILESIZE); - ////pfts->totalProgress = ft->dwBytesDone; - ////pfts->szWorkingDir = ft->szSavePath; - //pfts.tszCurrentFile = fullPath; - //pfts.currentFileSize = transfers[i]->GetUintProp(Transfer::P_FILESIZE); - ////pfts->currentFileTime = ft->dwThisFileDate; - ////pfts->currentFileProgress = ft->dwFileBytesDone; - - /*if (ProtoBroadcastAck(hContact, ACKTYPE_FILE, ACKRESULT_FILERESUME, (HANDLE)oid, (LPARAM)&pfts)) - return 0;*/ - - if ( !transfer->Accept((char *)ptrA(::mir_utf8encodeW(fullPath)), success) || !success) - return 0; + //pfts.totalBytes = ftp.files[fOid].size; + //pfts.totalProgress = ftp.files[fOid].transfered; + //pfts.tszWorkingDir = mir_wstrdup(szPath); + //pfts.currentFileNumber = 0; + //pfts.tszCurrentFile = mir_wstrdup(fullPath); + ////pfts.tszCurrentFile = ::mir_utf8decodeW(data); + //pfts.currentFileSize = ftp.files[fOid].size; + //pfts.currentFileProgress = ftp.files[fOid].transfered; + + //if ( !ProtoBroadcastAck(hContact, ACKTYPE_FILE, ACKRESULT_FILERESUME, (HANDLE)oid, (LPARAM)&pfts)) + if ( !transfer->Accept((char *)ptrA(::mir_utf8encodeW(fullPath)), success) || !success) + { + this->Log(L"Cannot accept file transfer"); + this->transferList.remove_val(transfer); + } } return hTransfer; @@ -195,16 +199,22 @@ int __cdecl CSkypeProto::FileCancel( HANDLE hContact, HANDLE hTransfer ) { uint oid = (uint)hTransfer; - //SEString data; - /*MessageRef msgRef(oid); + MessageRef msgRef(oid); TransferRefs transfers; + Transfer::STATUS transferStatus; msgRef->GetTransfers(transfers); - for (uint i = 0; i < transfers.size(); i++)*/ - TransferRef transfer(oid); - if ( !transfer->Cancel()) - return 0; - - this->Log(L"Incoming file transfer is cancelled"); + for (uint i = 0; i < transfers.size(); i++) + { + auto transfer = transfers[i]; + transfer->GetPropStatus(transferStatus); + if (transferStatus <= Transfer::CANCELLED && this->transferList.contains(transfer)) + { + if ( !transfer->Cancel()) + this->Log(L"Incoming file transfer is cancelled"); + this->transferList.remove_val(transfer); + } + } + this->transferts.erase(this->transferts.find(oid)); return 1; } @@ -212,19 +222,23 @@ int __cdecl CSkypeProto::FileCancel( HANDLE hContact, HANDLE hTransfer ) int __cdecl CSkypeProto::FileDeny( HANDLE hContact, HANDLE hTransfer, const TCHAR* szReason ) { uint oid = (uint)hTransfer; - - //SEString data; - /*MessageRef msgRef(oid); + + MessageRef msgRef(oid); TransferRefs transfers; + Transfer::STATUS transferStatus; msgRef->GetTransfers(transfers); for (uint i = 0; i < transfers.size(); i++) - if ( !transfers[i]->Cancel()) - return 0;*/ - TransferRef transfer(oid); - if ( !transfer->Cancel()) - return 0; - - this->Log(L"Incoming file transfer is denied"); + { + auto transfer = transfers[i]; + transfer->GetPropStatus(transferStatus); + if (transferStatus <= Transfer::CANCELLED && this->transferList.contains(transfer)) + { + if ( !transfer->Cancel()) + this->Log(L"Incoming file transfer is denied"); + this->transferList.remove_val(transfer); + } + } + this->transferts.erase(this->transferts.find(oid)); return 1; } @@ -234,13 +248,27 @@ int __cdecl CSkypeProto::FileResume( HANDLE hTransfer, int* action, const TCH if ( !this->IsOnline()) return 1; + uint oid = (uint)hTransfer; + + //auto fOid = transfers[i]->getOID(); + FileTransferParam ftp = this->transferts[oid]; + + MessageRef msgRef(oid); + TransferRefs transfers; + msgRef->GetTransfers(transfers); + for (uint i = 0; i < transfers.size(); i++){} + switch (*action) { case FILERESUME_SKIP: /*if (ft->p2p_appID != 0) - p2p_sendStatus(ft, 603); + p2p_sendStatus(ft, 603); else - msnftp_sendAcceptReject (ft, false);*/ + msnftp_sendAcceptReject (ft, false);*/ + break; + + case FILERESUME_RESUME: + //replaceStrT(ft->std.tszCurrentFile, *szFilename); break; case FILERESUME_RENAME: @@ -251,13 +279,13 @@ int __cdecl CSkypeProto::FileResume( HANDLE hTransfer, int* action, const TCH /*bool fcrt = ft->create() != -1; if (ft->p2p_appID != 0) { - if (fcrt) - p2p_sendFeedStart(ft); + if (fcrt) + p2p_sendFeedStart(ft); - p2p_sendStatus(ft, fcrt ? 200 : 603); + p2p_sendStatus(ft, fcrt ? 200 : 603); } else - msnftp_sendAcceptReject (ft, fcrt);*/ + msnftp_sendAcceptReject (ft, fcrt);*/ //ProtoBroadcastAck(ft->std.hContact, ACKTYPE_FILE, ACKRESULT_INITIALISING, ft, 0); break; @@ -336,7 +364,7 @@ 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, @@ -402,7 +430,7 @@ int __cdecl CSkypeProto::SendContacts(HANDLE hContact, int flags, int nContacts, for (int i = 0; i < nContacts; i++) { CContact::Ref contact; - + ptrW csid(::db_get_wsa(hContactsList[i], this->m_szModuleName, SKYPE_SETTINGS_SID)); this->GetContact((char *)ptrA(::mir_utf8encodeW(csid)), contact); contacts.append(contact); @@ -416,7 +444,7 @@ int __cdecl CSkypeProto::SendContacts(HANDLE hContact, int flags, int nContacts, // todo: bad hack CMessage::Refs msgs; this->GetMessageListByType(Message::POSTED_CONTACTS, true, msgs, timestamp); - + if (msgs.size() == 0) return 0; @@ -449,30 +477,51 @@ HANDLE __cdecl CSkypeProto::SendFile(HANDLE hContact, const TCHAR *szDescription if ( !conversation) return 0; + FileTransferParam ftp; + ftp.pfts.flags = PFTS_SENDING | PFTS_UNICODE; + ftp.pfts.hContact = hContact; + for (ftp.pfts.totalFiles = 0; ppszFiles[ftp.pfts.totalFiles]; ftp.pfts.totalFiles++); + ftp.pfts.ptszFiles = new wchar_t*[ftp.pfts.totalFiles + 1]; + + wchar_t *wd = new wchar_t[wcslen(ppszFiles[0]) + 1]; + wcscpy(wd, ppszFiles[0]); + PathRemoveFileSpec(wd); + ftp.pfts.tszWorkingDir = wd; + SEFilenameList fileList; - //for (int i = 0; ppszFiles[i]; i++) - fileList.append((char *)ptrA(::mir_utf8encodeW(ppszFiles[0]))); + for (int i = 0; ppszFiles[i]; i++) + { + ftp.pfts.ptszFiles[i] = ::mir_wstrdup(ppszFiles[i]); + fileList.append((char *)ptrA(::mir_utf8encodeW(ppszFiles[i]))); + } auto error = TRANSFER_OPEN_SUCCESS; SEFilename errFile; MessageRef msgRef; if ( !conversation->PostFiles(fileList, " ", error, errFile, msgRef) || error) - return 0; + return 0; + SEString data; TransferRefs transfers; if (msgRef->GetTransfers(transfers)) { - //for (uint i = 0; i < transfers.size(); i++) + for (uint i = 0; i < transfers.size(); i++) { - auto transfer = transfers[0]; - transfer.fetch(); - this->transferList.append(transfer); + transfers[i].fetch(); + this->transferList.append(transfers[i]); + + transfers[i]->GetPropFilesize(data); + Sid::uint64 size = data.toUInt64(); - return (HANDLE)transfer->getOID(); + ftp.files.insert(std::make_pair(transfers[i]->getOID(), FileParam(size))); + ftp.pfts.totalBytes += size; } } - //return (HANDLE)msgRef->getOID(); + auto oid = msgRef->getOID(); + this->transferts.insert(std::make_pair(oid, ftp)); + + return (HANDLE)oid; } return 0; @@ -507,16 +556,16 @@ int CSkypeProto::SetStatus(int new_status) { switch (new_status) { - case ID_STATUS_OCCUPIED: - new_status = ID_STATUS_DND; + case ID_STATUS_OCCUPIED: + new_status = ID_STATUS_DND; break; - case ID_STATUS_FREECHAT: - new_status = ID_STATUS_ONLINE; + case ID_STATUS_FREECHAT: + new_status = ID_STATUS_ONLINE; break; - case ID_STATUS_ONTHEPHONE: - case ID_STATUS_OUTTOLUNCH: - case ID_STATUS_NA: - new_status = ID_STATUS_AWAY; + case ID_STATUS_ONTHEPHONE: + case ID_STATUS_OUTTOLUNCH: + case ID_STATUS_NA: + new_status = ID_STATUS_AWAY; break; } @@ -588,13 +637,13 @@ int __cdecl CSkypeProto::UserIsTyping(HANDLE hContact, int type) { switch (type) { - case PROTOTYPE_SELFTYPING_ON: - conversation->SetMyTextStatusTo(Participant::WRITING); - return 0; + case PROTOTYPE_SELFTYPING_ON: + conversation->SetMyTextStatusTo(Participant::WRITING); + return 0; - case PROTOTYPE_SELFTYPING_OFF: - conversation->SetMyTextStatusTo(Participant::READING); //todo: mb TEXT_UNKNOWN? - return 0; + case PROTOTYPE_SELFTYPING_OFF: + conversation->SetMyTextStatusTo(Participant::READING); //todo: mb TEXT_UNKNOWN? + return 0; } } } @@ -615,7 +664,7 @@ int __cdecl CSkypeProto::OnEvent(PROTOEVENTTYPE eventType, WPARAM wParam, LPARAM case EV_PROTO_ONOPTIONS: return this->OnOptionsInit(wParam,lParam); - + case EV_PROTO_ONCONTACTDELETED: return this->OnContactDeleted(wParam, lParam); diff --git a/protocols/Skype/src/skype_proto.h b/protocols/Skype/src/skype_proto.h index 20ae6437e0..0ba3a953fa 100644 --- a/protocols/Skype/src/skype_proto.h +++ b/protocols/Skype/src/skype_proto.h @@ -119,6 +119,47 @@ struct PasswordChangeBoxParam } }; +struct FileParam +{ + bool isCanceled; + bool isCompleted; + + unsigned __int64 size; + unsigned __int64 transfered; + + FileParam() { } + FileParam(unsigned __int64 size) + { + this->size = size; + this->transfered = 0; + this->isCanceled = this->isCompleted = false; + } +}; + +struct FileTransferParam +{ + //CTransfer::Refs transfers; + PROTOFILETRANSFERSTATUS pfts; + std::map files; + + FileTransferParam() + { + this->pfts.cbSize = sizeof(this->pfts); + this->pfts.flags = 0; + this->pfts.currentFileNumber = 0; + this->pfts.currentFileProgress = 0; + this->pfts.currentFileSize = 0; + this->pfts.currentFileTime = 0; + this->pfts.totalBytes = 0; + this->pfts.totalFiles = 0; + this->pfts.totalProgress = 0; + this->pfts.tszWorkingDir = NULL; + this->pfts.wszCurrentFile = NULL; + + //Sid::fetch(this->transfers); + } +}; + class ChatMember; class ChatRoom; @@ -314,6 +355,8 @@ protected: // transfer static wchar_t *TransferFailureReasons[]; + std::map transferts; + void OnFileEvent(const ConversationRef &conversation, const MessageRef &message); void OnTransferChanged(const TransferRef &transfer, int prop); diff --git a/protocols/Skype/src/skype_transfers.cpp b/protocols/Skype/src/skype_transfers.cpp index 222ee0ecf7..920e3c4d99 100644 --- a/protocols/Skype/src/skype_transfers.cpp +++ b/protocols/Skype/src/skype_transfers.cpp @@ -4,14 +4,14 @@ wchar_t *CSkypeProto::TransferFailureReasons[] = { LPGENW("") /* --- */, LPGENW("SENDER_NOT_AUTHORISED") /* SENDER_NOT_AUTHORISED */, - LPGENW("REMOTELY_CANCELLED") /* REMOTELY_CANCELLED */, - LPGENW("FAILED_READ") /* FAILED_READ */, - LPGENW("FAILED_REMOTE_READ") /* FAILED_REMOTE_READ */, - LPGENW("FAILED_WRITE") /* FAILED_WRITE */, - LPGENW("FAILED_REMOTE_WRITE") /* FAILED_REMOTE_WRITE */, - LPGENW("REMOTE_DOES_NOT_SUPPORT_FT") /* REMOTE_DOES_NOT_SUPPORT_FT */, - LPGENW("REMOTE_OFFLINE_FOR_TOO_LONG") /* REMOTE_OFFLINE_FOR_TOO_LONG */, - LPGENW("TOO_MANY_PARALLEL") /* TOO_MANY_PARALLEL */, + LPGENW("REMOTELY_CANCELLED") /* REMOTELY_CANCELLED */, + LPGENW("FAILED_READ") /* FAILED_READ */, + LPGENW("FAILED_REMOTE_READ") /* FAILED_REMOTE_READ */, + LPGENW("FAILED_WRITE") /* FAILED_WRITE */, + LPGENW("FAILED_REMOTE_WRITE") /* FAILED_REMOTE_WRITE */, + LPGENW("REMOTE_DOES_NOT_SUPPORT_FT") /* REMOTE_DOES_NOT_SUPPORT_FT */, + LPGENW("REMOTE_OFFLINE_FOR_TOO_LONG") /* REMOTE_OFFLINE_FOR_TOO_LONG */, + LPGENW("TOO_MANY_PARALLEL") /* TOO_MANY_PARALLEL */, LPGENW("PLACEHOLDER_TIMEOUT") /* PLACEHOLDER_TIMEOUT */ }; @@ -23,47 +23,71 @@ void CSkypeProto::OnTransferChanged(const TransferRef &transfer, int prop) { Transfer::FAILUREREASON reason; - /*SEBinary guid; + SEBinary guid; transfer->GetPropChatmsgGuid(guid); MessageRef msgRef; this->GetMessageByGuid(guid, msgRef); - - uint oid = msgRef->getOID();*/ - uint oid = transfer->getOID(); + uint oid = msgRef->getOID(); - SEString data; - transfer->GetPropPartnerHandle(data); - HANDLE hContact = this->GetContactBySid(ptrW(::mir_utf8decodeW(data))); + uint fOid = transfer->getOID(); Transfer::STATUS status; transfer->GetPropStatus(status); switch(status) { case Transfer::CONNECTING: - this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, (HANDLE)oid, 0); + this->SendBroadcast(this->transferts[oid].pfts.hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, (HANDLE)oid, 0); break; case Transfer::TRANSFERRING: case Transfer::TRANSFERRING_OVER_RELAY: - this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)oid, 0); + this->SendBroadcast(this->transferts[oid].pfts.hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)oid, 0); break; case Transfer::FAILED: transfer->GetPropFailurereason(reason); - this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)oid, (LPARAM)CSkypeProto::TransferFailureReasons[reason]); + this->Log(L"File transfer failed: %s", CSkypeProto::TransferFailureReasons[reason]); this->transferList.remove_val(transfer); + this->transferts[oid].files[fOid].isCanceled = true; break; case Transfer::COMPLETED: - this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, (HANDLE)oid, 0); this->transferList.remove_val(transfer); + this->transferts[oid].files[fOid].isCompleted = true; + this->transferts[oid].pfts.totalProgress += this->transferts[oid].files[fOid].size - this->transferts[oid].files[fOid].transfered; break; case Transfer::CANCELLED: case Transfer::CANCELLED_BY_REMOTE: transfer->GetPropFailurereason(reason); - this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)oid, (LPARAM)CSkypeProto::TransferFailureReasons[reason]); + this->Log(L"File transfer cancelled: %s", CSkypeProto::TransferFailureReasons[reason]); this->transferList.remove_val(transfer); + this->transferts[oid].files[fOid].isCanceled = true; break; } + + int isNotAll = false; + for (auto i = this->transferts[oid].files.begin(); i != this->transferts[oid].files.end(); i++) + if ( !(i->second.isCanceled || i->second.isCompleted)) + { + isNotAll = true; + break; + } + if (isNotAll) + { + SEString data; + uint fOid = transfer->getOID(); + transfer->GetPropBytestransferred(data); + Sid::uint64 tb = data.toUInt64(); + this->transferts[oid].pfts.totalProgress += tb; + this->transferts[oid].files[fOid].transfered = tb; + + this->SendBroadcast(this->transferts[oid].pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)oid, (LPARAM)&this->transferts[oid].pfts); + } + else + { + this->SendBroadcast(this->transferts[oid].pfts.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, (HANDLE)oid, 0); + delete [] this->transferts[oid].pfts.ptszFiles; + this->transferts.erase(this->transferts.find(oid)); + } } break; @@ -71,30 +95,21 @@ void CSkypeProto::OnTransferChanged(const TransferRef &transfer, int prop) { SEString data; - uint oid = transfer->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(ptrW(::mir_utf8decodeW(data))); - pfts.hContact = hContact; - - transfer->GetPropFilename(data); - pfts.szCurrentFile = ::mir_strdup(data); + SEBinary guid; + transfer->GetPropChatmsgGuid(guid); - pfts.pszFiles = &pfts.szCurrentFile; + MessageRef msgRef; + this->GetMessageByGuid(guid, msgRef); - transfer->GetPropFilesize(data); - pfts.totalBytes = pfts.currentFileSize = data.toUInt64(); + uint oid = msgRef->getOID(); + uint fOid = transfer->getOID(); transfer->GetPropBytestransferred(data); - pfts.totalProgress = pfts.currentFileProgress = data.toUInt64(); + Sid::uint64 tb = data.toUInt64(); + this->transferts[oid].pfts.totalProgress += tb; + this->transferts[oid].files[fOid].transfered = tb; - this->SendBroadcast(hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)oid, (LPARAM)&pfts); + this->SendBroadcast(this->transferts[oid].pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)oid, (LPARAM)&this->transferts[oid].pfts); } break; } @@ -103,81 +118,74 @@ void CSkypeProto::OnTransferChanged(const TransferRef &transfer, int prop) void CSkypeProto::OnFileEvent(const ConversationRef &conversation, const MessageRef &message) { SEString data; - //bool isRecvFiles = false; Transfer::TYPE transferType; Transfer::STATUS transferStatus; + ContactRef author; + message->GetPropAuthor(data); + this->GetContact(data, author); + TransferRefs transfers; message->GetTransfers(transfers); - wchar_t **files = new wchar_t*[transfers.size()]; + + FileTransferParam ftp; + ftp.pfts.flags = PFTS_RECEIVING | PFTS_UNICODE; + ftp.pfts.hContact = this->AddContact(author, true); + ftp.pfts.totalFiles = transfers.size(); + ftp.pfts.ptszFiles = new wchar_t*[transfers.size() + 1]; + + int nifc = 0; for (size_t i = 0; i < transfers.size(); i++) { auto transfer = transfers[i]; - transfer->GetPropFilename(data); - files[i] = ::mir_utf8decodeW(data); - // 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) + if (transferStatus == Transfer::NEW || transferStatus == Transfer::PLACEHOLDER) { transfer->GetPropType(transferType); if (transferType == Transfer::INCOMING) { - //isRecvFiles = true; + transfer->GetPropFilename(data); + ftp.pfts.ptszFiles[nifc++] = ::mir_utf8decodeW(data); - this->transferList.append(transfer); transfer.fetch(); + this->transferList.append(transfer); + //transfer.fetch(); - uint timestamp; - message->GetPropTimestamp(timestamp); - - ContactRef author; - message->GetPropAuthor(data); - this->GetContact(data, author); - - HANDLE hContact = this->AddContact(author, true); + transfer->GetPropFilesize(data); + Sid::uint64 size = data.toUInt64(); - PROTORECVFILET pre = {0}; - pre.flags = PREF_TCHAR; - pre.fileCount = (int)transfers.size(); - pre.timestamp = timestamp; - pre.tszDescription = L""; - pre.ptszFiles = files; - pre.lParam = (LPARAM)transfer->getOID(); - ::ProtoChainRecvFile(hContact, &pre); - } - else if (transferType == Transfer::PLACEHOLDER) - { - this->transferList.append(transfer); - transfer.fetch(); + ftp.files.insert(std::make_pair(transfer->getOID(), FileParam(size))); + ftp.pfts.totalBytes += size; } } } - /*files[transfers.size()] = NULL; - if (isRecvFiles) + if (nifc > 0) { uint timestamp; message->GetPropTimestamp(timestamp); - ContactRef author; - message->GetPropAuthor(data); - this->GetContact(data, author); - - HANDLE hContact = this->AddContact(author, true); + auto oid = message->getOID(); + + this->transferts.insert(std::make_pair(oid, ftp)); PROTORECVFILET pre = {0}; pre.flags = PREF_TCHAR; - pre.fileCount = transfers.size(); + pre.fileCount = ftp.pfts.totalFiles; pre.timestamp = timestamp; pre.tszDescription = L""; - pre.ptszFiles = files; - pre.lParam = (LPARAM)message->getOID(); - ::ProtoChainRecvFile(hContact, &pre); - }*/ + pre.ptszFiles = ftp.pfts.ptszFiles; + pre.lParam = (LPARAM)oid; + ::ProtoChainRecvFile(ftp.pfts.hContact, &pre); + } + else + { + delete [] ftp.pfts.ptszFiles; + } } \ No newline at end of file diff --git a/protocols/Skype/src/skypekit/contact.cpp b/protocols/Skype/src/skypekit/contact.cpp index cd6afab9ef..c7a1a3247d 100644 --- a/protocols/Skype/src/skypekit/contact.cpp +++ b/protocols/Skype/src/skypekit/contact.cpp @@ -28,14 +28,18 @@ SEString CContact::GetNick() this->GetPropPstnnumber(result); else { + SEString sid; + this->GetIdentity(sid); + this->GetPropDisplayname(result); if (this->proto && this->proto->login) { - SEString sid; - this->GetIdentity(sid); if (sid.equals(result)) this->GetPropFullname(result); } + + if (result.size() == 0) + result = sid; } return result; } -- cgit v1.2.3