From 0a776a22a99c20a23763aac28209a00a36126b7b Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Mon, 25 Aug 2014 18:32:33 +0000 Subject: Tox: - updated tox core - fixdd contacts adding - some code for file sending git-svn-id: http://svn.miranda-ng.org/main/trunk@10320 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Tox/src/common.h | 1 + protocols/Tox/src/file_transfer.h | 151 ++++++++++++++++++++++++++++++++++++ protocols/Tox/src/tox/tox.h | 5 -- protocols/Tox/src/tox_account.cpp | 11 +-- protocols/Tox/src/tox_bootstrap.h | 2 - protocols/Tox/src/tox_contacts.cpp | 6 +- protocols/Tox/src/tox_events.cpp | 12 +++ protocols/Tox/src/tox_proto.cpp | 24 +++++- protocols/Tox/src/tox_proto.h | 11 ++- protocols/Tox/src/tox_transfers.cpp | 27 +++++++ 10 files changed, 227 insertions(+), 23 deletions(-) create mode 100644 protocols/Tox/src/file_transfer.h create mode 100644 protocols/Tox/src/tox_transfers.cpp (limited to 'protocols/Tox/src') diff --git a/protocols/Tox/src/common.h b/protocols/Tox/src/common.h index 9518d62e3a..f50d7393d2 100644 --- a/protocols/Tox/src/common.h +++ b/protocols/Tox/src/common.h @@ -32,6 +32,7 @@ #include "version.h" #include "resource.h" #include "tox_proto.h" +#include "file_transfer.h" extern HINSTANCE g_hInstance; diff --git a/protocols/Tox/src/file_transfer.h b/protocols/Tox/src/file_transfer.h new file mode 100644 index 0000000000..d131802973 --- /dev/null +++ b/protocols/Tox/src/file_transfer.h @@ -0,0 +1,151 @@ +#ifndef _FILE_TRANSFER_H_ +#define _FILE_TRANSFER_H_ + +class CFileTransfer; + +class CFile +{ +private: + HANDLE hProcess; + + const CFileTransfer *transfer; + + char *name; + const TCHAR *path; + size_t size; + +public: + CFile(const CFileTransfer *fileTransfer, const TCHAR *filePath, size_t fileSize) + { + transfer = fileTransfer; + + path = filePath; + name = strrchr(ptrA(mir_utf8encodeT(path)), '\\'); + size = fileSize; + } + + ~CFile() + { + mir_free(name); + } + + void SetHandle(HANDLE hFileProcess) + { + hProcess = hFileProcess; + } + + const TCHAR* GetPath() const + { + return path; + } + + const char* GetName() const + { + return name; + } + + size_t GetSize() const + { + return size; + } +}; + +class CFileTransfer +{ +private: + HANDLE hProcess; + LIST files; + +public: + PROTOFILETRANSFERSTATUS pfts; + + CFileTransfer(MCONTACT hContact, ULONG hProcess, DWORD flags) : + files(1) + { + pfts.cbSize = sizeof(pfts); + pfts.flags = PFTS_TCHAR | flags; + pfts.hContact = hContact; + pfts.currentFileNumber = 0; + pfts.currentFileProgress = 0; + pfts.currentFileSize = 0; + pfts.totalBytes = 0; + pfts.totalFiles = 0; + pfts.totalProgress = 0; + pfts.pszFiles = NULL; + pfts.tszWorkingDir = NULL; + pfts.tszCurrentFile = NULL; + + this->hProcess = (HANDLE)hProcess; + } + + ~CFileTransfer() + { + if (pfts.tszWorkingDir) + mir_free(pfts.tszWorkingDir); + if (pfts.ptszFiles) + { + for (int i = 0; pfts.ptszFiles[i]; i++) + { + if (pfts.ptszFiles[i]) mir_free(pfts.ptszFiles[i]); + } + mir_free(pfts.ptszFiles); + } + } + + void ProcessTransferedFiles(TCHAR** ppszFiles) + { + for (pfts.totalFiles = 0; ppszFiles[pfts.totalFiles]; pfts.totalFiles++); + pfts.ptszFiles = (TCHAR**)mir_alloc(sizeof(TCHAR*)*(pfts.totalFiles + 1)); + pfts.ptszFiles[pfts.totalFiles] = NULL; + for (int i = 0; ppszFiles[i]; i++) + { + if (!pfts.tszWorkingDir) + { + wchar_t *path = ppszFiles[i]; + int length = wcsrchr(path, '\\') - path; + pfts.tszWorkingDir = (TCHAR*)mir_alloc(sizeof(TCHAR)*(length + 1)); + lstrcpyn(pfts.tszWorkingDir, ppszFiles[i], length + 1); + pfts.tszWorkingDir[length] = '\0'; + } + + pfts.ptszFiles[i] = mir_tstrdup(ppszFiles[i]); + + size_t fileSize = 0; + FILE *file = _tfopen(ppszFiles[i], _T("rb")); + if (file != NULL) + { + fseek(file, 0, SEEK_END); + pfts.totalBytes += fileSize = ftell(file); + fseek(file, 0, SEEK_SET); + fclose(file); + } + + files.insert(new CFile(this, pfts.ptszFiles[i], fileSize)); + } + } + + int GetFileCount() const + { + return files.getCount(); + } + + CFile * const GetFileAt(int idx) const + { + return files[idx]; + } + + HANDLE GetTransferHandler() const + { + return hProcess; + } +}; + +class CFileSendTransfer : public CFileTransfer +{ +public: + CFileSendTransfer(MCONTACT hContact, ULONG hProcess) : CFileTransfer(hContact, hProcess, PFTS_SENDING) + { + } +}; + +#endif //_FILE_TRANSFER_H_ \ No newline at end of file diff --git a/protocols/Tox/src/tox/tox.h b/protocols/Tox/src/tox/tox.h index c9a6bc709c..5810c1289c 100644 --- a/protocols/Tox/src/tox/tox.h +++ b/protocols/Tox/src/tox/tox.h @@ -267,11 +267,6 @@ int tox_set_user_is_typing(Tox *tox, int32_t friendnumber, uint8_t is_typing); */ uint8_t tox_get_is_typing(const Tox *tox, int32_t friendnumber); -/* Sets whether we send read receipts for friendnumber. - * This function is not lazy, and it will fail if yesno is not (0 or 1). - */ -void tox_set_sends_receipts(Tox *tox, int32_t friendnumber, int yesno); - /* Return the number of friends in the instance m. * You should use this to determine how much memory to allocate * for copy_friendlist. */ diff --git a/protocols/Tox/src/tox_account.cpp b/protocols/Tox/src/tox_account.cpp index 8118149cdb..8d3b0715f6 100644 --- a/protocols/Tox/src/tox_account.cpp +++ b/protocols/Tox/src/tox_account.cpp @@ -33,6 +33,7 @@ void CToxProto::InitToxCore() tox_callback_user_status(tox, OnUserStatusChanged, this); tox_callback_read_receipt(tox, OnReadReceipt, this); tox_callback_connection_status(tox, OnConnectionStatusChanged, this); + tox_callback_file_control(tox, OnFileRequest, this); LoadToxData(); @@ -88,7 +89,6 @@ void CToxProto::PollingThread(void*) debugLogA("CToxProto::PollingThread: entering"); isConnected = false; - time_t timestamp0 = time(NULL); DoBootstrap(); while (!isTerminated) @@ -104,16 +104,13 @@ void CToxProto::PollingThread(void*) LoadContactList(); - m_iStatus = ID_STATUS_ONLINE; + debugLogA("CToxProto::PollingThread: changing status from %i to %i", ID_STATUS_CONNECTING, m_iDesiredStatus); + m_iStatus = m_iDesiredStatus; ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)ID_STATUS_CONNECTING, m_iStatus); } else { - time_t timestamp1 = time(NULL); - if (timestamp0 + 250 < timestamp1) { - timestamp0 = timestamp1; - DoBootstrap(); - } + DoBootstrap(); } } } diff --git a/protocols/Tox/src/tox_bootstrap.h b/protocols/Tox/src/tox_bootstrap.h index 4c128ab000..f8faa30584 100644 --- a/protocols/Tox/src/tox_bootstrap.h +++ b/protocols/Tox/src/tox_bootstrap.h @@ -1,8 +1,6 @@ #ifndef _TOX_BOOTSTRAP_H_ #define _TOX_BOOTSTRAP_H_ -#include "common.h" - struct bootstrap_node { char *address; uint16_t port; diff --git a/protocols/Tox/src/tox_contacts.cpp b/protocols/Tox/src/tox_contacts.cpp index 515aa13b3b..e9e3622da9 100644 --- a/protocols/Tox/src/tox_contacts.cpp +++ b/protocols/Tox/src/tox_contacts.cpp @@ -56,19 +56,17 @@ MCONTACT CToxProto::FindContact(const std::string &id) { MCONTACT hContact = NULL; - //EnterCriticalSection(&contact_search_lock); + //mir_cs(contact_search_lock); for (hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName)) { std::string contactId = ToxAddressToId(getStringA(hContact, TOX_SETTINGS_ID)); - if (id.compare(contactId) == 0) + if (id == contactId) { break; } } - //LeaveCriticalSection(&contact_search_lock); - return hContact; } diff --git a/protocols/Tox/src/tox_events.cpp b/protocols/Tox/src/tox_events.cpp index 39824f1038..e55eba54eb 100644 --- a/protocols/Tox/src/tox_events.cpp +++ b/protocols/Tox/src/tox_events.cpp @@ -218,4 +218,16 @@ void CToxProto::OnReadReceipt(Tox *tox, int32_t number, uint32_t receipt, void * ACKRESULT_SUCCESS, (HANDLE)receipt, 0); } +} + +void CToxProto::OnFileRequest(Tox *tox, int32_t number, uint8_t isSend, uint8_t fileNumber, uint8_t type, const uint8_t *data, uint16_t length, void *arg) +{ + CToxProto *proto = (CToxProto*)arg; + MCONTACT hContact = proto->FindContact(number); + if (hContact) + { + if (isSend && type == TOX_FILECONTROL_ACCEPT) + { + } + } } \ No newline at end of file diff --git a/protocols/Tox/src/tox_proto.cpp b/protocols/Tox/src/tox_proto.cpp index 769679cdf8..9547b33f90 100644 --- a/protocols/Tox/src/tox_proto.cpp +++ b/protocols/Tox/src/tox_proto.cpp @@ -1,7 +1,9 @@ #include "common.h" CToxProto::CToxProto(const char* protoName, const TCHAR* userName) : -PROTO(protoName, userName) + PROTO(protoName, userName), + fileSendQueue(1, NumericKeySortT), + hFileProcess(0) { InitToxCore(); @@ -61,7 +63,7 @@ MCONTACT __cdecl CToxProto::AddToList(int flags, PROTOSEARCHRESULT* psr) std::string address(mir_t2a(psr->id)); std::string id = ToxAddressToId(address); std::string myId = ToxAddressToId(getStringA(TOX_SETTINGS_ID)); - if (myId.compare(id)) + if (myId == id) { debugLogA("CToxProto::AddToList: you cannot add yourself to friend list"); return NULL; @@ -215,7 +217,16 @@ int __cdecl CToxProto::RecvMsg(MCONTACT hContact, PROTORECVEVENT *pre) int __cdecl CToxProto::RecvUrl(MCONTACT hContact, PROTORECVEVENT*) { return 0; } int __cdecl CToxProto::SendContacts(MCONTACT hContact, int flags, int nContacts, MCONTACT* hContactsList) { return 0; } -HANDLE __cdecl CToxProto::SendFile(MCONTACT hContact, const PROTOCHAR* szDescription, PROTOCHAR** ppszFiles) { return 0; } + +HANDLE __cdecl CToxProto::SendFile(MCONTACT hContact, const PROTOCHAR* szDescription, PROTOCHAR** ppszFiles) +{ + CFileTransfer *transfer = new CFileSendTransfer(hContact, InterlockedIncrement(&hFileProcess)); + transfer->ProcessTransferedFiles(ppszFiles); + + ForkThread(&CToxProto::SendFilesAsync, transfer); + + return transfer->GetTransferHandler(); +} int __cdecl CToxProto::SendMsg(MCONTACT hContact, int flags, const char* msg) { @@ -257,10 +268,15 @@ int __cdecl CToxProto::SetStatus(int iNewStatus) SetAllContactsStatus(ID_STATUS_OFFLINE); } - m_iStatus = ID_STATUS_OFFLINE; + m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; } else { + if (old_status == ID_STATUS_CONNECTING) + { + return 0; + } + if (old_status == ID_STATUS_OFFLINE && !IsOnline()) { m_iStatus = ID_STATUS_CONNECTING; diff --git a/protocols/Tox/src/tox_proto.h b/protocols/Tox/src/tox_proto.h index 1154f58a59..addeec0037 100644 --- a/protocols/Tox/src/tox_proto.h +++ b/protocols/Tox/src/tox_proto.h @@ -1,7 +1,7 @@ #ifndef _TOX_PROTO_H_ #define _TOX_PROTO_H_ -#include "common.h" +class CFile; struct CToxProto : public PROTO { @@ -75,6 +75,8 @@ private: bool isTerminated; bool isConnected; HANDLE hNetlibUser; + ULONG hFileProcess; + LIST fileSendQueue; // tox void InitToxCore(); @@ -116,6 +118,9 @@ private: static void OnConnectionStatusChanged(Tox *tox, const int number, const uint8_t status, void *arg); static void OnReadReceipt(Tox *tox, int32_t number, uint32_t receipt, void *arg); + //static void OnFileControlCallback(Tox *tox, int32_t number, uint8_t hFile, uint64_t fileSize, uint8_t *name, uint16_t nameSize, void *arg); + static void OnFileRequest(Tox *tox, int32_t number, uint8_t isSend, uint8_t fileNumber, uint8_t type, const uint8_t *data, uint16_t length, void *arg); + // contacts WORD GetContactStatus(MCONTACT hContact); bool IsContactOnline(MCONTACT hContact); @@ -133,6 +138,10 @@ private: void __cdecl SearchByIdAsync(void* arg); void __cdecl SearchByNameAsync(void* arg); + // file transfer + static int FileSendQueueCompare(const CFile* p1, const CFile* p2); + void __cdecl SendFilesAsync(void* arg); + // utils TOX_USERSTATUS MirandaToToxStatus(int status); int ToxToMirandaStatus(TOX_USERSTATUS userstatus); diff --git a/protocols/Tox/src/tox_transfers.cpp b/protocols/Tox/src/tox_transfers.cpp new file mode 100644 index 0000000000..b15ac1838f --- /dev/null +++ b/protocols/Tox/src/tox_transfers.cpp @@ -0,0 +1,27 @@ +#include "common.h" + +int CToxProto::FileSendQueueCompare(const CFile* p1, const CFile* p2) +{ + return 0; +} + +void CToxProto::SendFilesAsync(void* arg) +{ + CFileTransfer *ftp = (CFileTransfer*)arg; + + std::string toxId(getStringA(ftp->pfts.hContact, TOX_SETTINGS_ID)); + std::vector clientId = HexStringToData(toxId); + + uint32_t number = tox_get_friend_number(tox, clientId.data()); + + for (int i = 0; ftp->GetFileCount(); i++) + { + CFile *file = ftp->GetFileAt(i); + int hFile = tox_new_file_sender(tox, number, file->GetSize(), (uint8_t*)file->GetName(), strlen(file->GetName())); + if (hFile < 0) + { + debugLogA("CToxProto::SendFilesAsync: cannot send file"); + } + file->SetHandle((HANDLE)hFile); + } +} \ No newline at end of file -- cgit v1.2.3