From 760f8d30226213cb615180b462fc266dca955451 Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Sun, 31 Aug 2014 19:16:30 +0000 Subject: Tox: - fox for crush on auth request - some fixes in file transfer git-svn-id: http://svn.miranda-ng.org/main/trunk@10350 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Tox/src/common.h | 2 + protocols/Tox/src/tox_contacts.cpp | 3 +- protocols/Tox/src/tox_proto.cpp | 105 ----------------- protocols/Tox/src/tox_proto.h | 5 +- protocols/Tox/src/tox_transfer.cpp | 230 ++++++++++++++++++++++++++++++------- 5 files changed, 194 insertions(+), 151 deletions(-) diff --git a/protocols/Tox/src/common.h b/protocols/Tox/src/common.h index e7fd4ce733..9ee450e5c2 100644 --- a/protocols/Tox/src/common.h +++ b/protocols/Tox/src/common.h @@ -39,6 +39,8 @@ extern HINSTANCE g_hInstance; #define MODULE "Tox" +#define TOX_ERROR -1 + #define TOX_SETTINGS_ID "ToxID" #define TOX_SETTINGS_GROUP "DefaultGroup" diff --git a/protocols/Tox/src/tox_contacts.cpp b/protocols/Tox/src/tox_contacts.cpp index b696c6b70c..27898916cc 100644 --- a/protocols/Tox/src/tox_contacts.cpp +++ b/protocols/Tox/src/tox_contacts.cpp @@ -166,7 +166,7 @@ void CToxProto::OnFriendRequest(Tox *tox, const uint8_t *address, const uint8_t pre.timestamp = time(NULL); pre.lParam = (DWORD)(sizeof(DWORD)* 2 + id.length() + messageSize + 5); - /*blob is: 0(DWORD), hContact(DWORD), nick(ASCIIZ), firstName(ASCIIZ), lastName(ASCIIZ), sid(ASCIIZ), reason(ASCIIZ)*/ + /*blob is: 0(DWORD), hContact(DWORD), nick(ASCIIZ), firstName(ASCIIZ), lastName(ASCIIZ), id(ASCIIZ), reason(ASCIIZ)*/ PBYTE pBlob, pCurBlob; pCurBlob = pBlob = (PBYTE)mir_calloc(pre.lParam); @@ -178,6 +178,7 @@ void CToxProto::OnFriendRequest(Tox *tox, const uint8_t *address, const uint8_t strcpy((char *)pCurBlob, id.c_str()); pCurBlob += id.length() + 1; strcpy((char *)pCurBlob, (char*)message); + pre.szMessage = (char*)pBlob; ProtoChainRecv(hContact, PSR_AUTH, 0, (LPARAM)&pre); } diff --git a/protocols/Tox/src/tox_proto.cpp b/protocols/Tox/src/tox_proto.cpp index e5bb613c8f..1ef5cf629a 100644 --- a/protocols/Tox/src/tox_proto.cpp +++ b/protocols/Tox/src/tox_proto.cpp @@ -145,71 +145,6 @@ int __cdecl CToxProto::AuthRequest(MCONTACT hContact, const PROTOCHAR* szMessage HANDLE __cdecl CToxProto::ChangeInfo(int iInfoType, void* pInfoData) { return 0; } -HANDLE __cdecl CToxProto::FileAllow(MCONTACT hContact, HANDLE hTransfer, const PROTOCHAR* tszPath) -{ - std::string toxId(getStringA(hContact, TOX_SETTINGS_ID)); - std::vector clientId = HexStringToData(toxId); - - uint32_t number = tox_get_friend_number(tox, clientId.data()); - uint8_t fileNumber = (uint8_t)hTransfer; - - FileTransferParam *transfer = transfers.at(fileNumber); - transfer->pfts.tszWorkingDir = mir_tstrdup(tszPath); - - //if (!ProtoBroadcastAck(hContact, ACKTYPE_FILE, ACKRESULT_FILERESUME, (HANDLE)fileNumber, (LPARAM)&transfer->pfts)) - { - tox_file_send_control(tox, number, 1, fileNumber, TOX_FILECONTROL_ACCEPT, NULL, 0); - } - - return hTransfer; -} - -int __cdecl CToxProto::FileCancel(MCONTACT hContact, HANDLE hTransfer) -{ - std::string toxId(getStringA(hContact, TOX_SETTINGS_ID)); - std::vector clientId = HexStringToData(toxId); - - uint32_t number = tox_get_friend_number(tox, clientId.data()); - int fileNumber = (int)hTransfer; - - transfers.erase(fileNumber); - - int result = tox_file_send_control(tox, number, 1, fileNumber, TOX_FILECONTROL_KILL, NULL, 0); - - return result + 1; -} - -int __cdecl CToxProto::FileDeny(MCONTACT hContact, HANDLE hTransfer, const PROTOCHAR*) -{ - return FileCancel(hContact, hTransfer); -} - -int __cdecl CToxProto::FileResume(HANDLE hTransfer, int* action, const PROTOCHAR** szFilename) -{ - uint8_t fileNumber = (uint8_t)hTransfer; - FileTransferParam *transfer = transfers.at(fileNumber); - - switch (*action) - { - case FILERESUME_SKIP: - /*if (ft->p2p_appID != 0) - p2p_sendStatus(ft, 603); - else - msnftp_sendAcceptReject (ft, false);*/ - break; - - case FILERESUME_RESUME: - //replaceStrT(ft->std.tszCurrentFile, *szFilename); - break; - - case FILERESUME_RENAME: - replaceStrT(transfer->pfts.tszCurrentFile, *szFilename); - break; - } - - return 0; -} - int __cdecl CToxProto::GetInfo(MCONTACT hContact, int infoType) { return 0; } HANDLE __cdecl CToxProto::SearchBasic(const PROTOCHAR* id) { return 0; } @@ -294,46 +229,6 @@ 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) -{ - std::string toxId(getStringA(hContact, TOX_SETTINGS_ID)); - std::vector clientId = HexStringToData(toxId); - - uint32_t number = tox_get_friend_number(tox, clientId.data()); - - TCHAR *fileName = _tcsrchr(ppszFiles[0], '\\') + 1; - - size_t fileDirLength = fileName - ppszFiles[0]; - TCHAR *fileDir = (TCHAR*)mir_alloc(sizeof(TCHAR)*fileDirLength); - _tcsncpy(fileDir, ppszFiles[0], fileDirLength); - fileDir[fileDirLength] = '\0'; - - size_t fileSize = 0; - FILE *file = _tfopen(ppszFiles[0], _T("rb")); - if (file != NULL) - { - fseek(file, 0, SEEK_END); - fileSize = ftell(file); - fseek(file, 0, SEEK_SET); - fclose(file); - } - - int fileNumber = tox_new_file_sender(tox, number, fileSize, (uint8_t*)(char*)ptrA(mir_utf8encodeT(fileName)), _tcslen(fileName)); - if (fileNumber < 0) - { - debugLogA("CToxProto::SendFilesAsync: cannot send file"); - return NULL; - } - - FileTransferParam *transfer = new FileTransferParam(fileNumber, fileName, fileSize); - transfer->pfts.hContact = hContact; - transfer->pfts.flags |= PFTS_RECEIVING; - transfer->pfts.tszWorkingDir = fileDir; - transfers[fileNumber] = transfer; - - return (HANDLE)fileNumber; -} - int __cdecl CToxProto::SendMsg(MCONTACT hContact, int flags, const char* msg) { std::string toxId(getStringA(hContact, TOX_SETTINGS_ID)); diff --git a/protocols/Tox/src/tox_proto.h b/protocols/Tox/src/tox_proto.h index 4718ac7c3f..c4dc2c3c8d 100644 --- a/protocols/Tox/src/tox_proto.h +++ b/protocols/Tox/src/tox_proto.h @@ -178,10 +178,13 @@ private: int __cdecl OnPreCreateMessage(WPARAM wParam, LPARAM lParam); // transfer + void AddToTransferList(FileTransferParam *transfer); + void RemoveFromTransferList(FileTransferParam *transfer); + void __cdecl SendFileAsync(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); + static void OnFileRequest(Tox *tox, int32_t number, uint8_t receive_send, uint8_t fileNumber, uint8_t type, const uint8_t *data, uint16_t length, void *arg); static void OnFriendFile(Tox *tox, int32_t number, uint8_t fileNumber, uint64_t fileSize, const uint8_t *fileName, uint16_t length, void *arg); static void OnFileData(Tox *tox, int32_t number, uint8_t fileNumber, const uint8_t *data, uint16_t length, void *arg); diff --git a/protocols/Tox/src/tox_transfer.cpp b/protocols/Tox/src/tox_transfer.cpp index 5a7162fb39..80309b30f5 100644 --- a/protocols/Tox/src/tox_transfer.cpp +++ b/protocols/Tox/src/tox_transfer.cpp @@ -1,49 +1,26 @@ #include "common.h" -void CToxProto::SendFileAsync(void* arg) +void CToxProto::AddToTransferList(FileTransferParam *transfer) { - FileTransferParam *transfer = (FileTransferParam*)arg; - - std::string toxId(getStringA(transfer->pfts.hContact, TOX_SETTINGS_ID)); - std::vector clientId = HexStringToData(toxId); - - uint32_t number = tox_get_friend_number(tox, clientId.data()); - if (number < 0) + if (transfers.find(transfer->number) != transfers.end()) { - return; + transfers[transfer->number] = transfer; } +} - size_t fileSize = transfer->pfts.currentFileSize; - size_t fileProgress = 0; - TCHAR filePath[MAX_PATH]; - mir_sntprintf(filePath, SIZEOF(filePath), _T("%s%s"), transfer->pfts.tszWorkingDir, transfer->pfts.tszCurrentFile); - - FILE *hFile = _wfopen(filePath, _T("rb")); - if (hFile != NULL) - { - size_t chunkSize = min(tox_file_data_size(tox, number), fileSize); - uint8_t *data = (uint8_t*)mir_alloc(chunkSize); - while (!feof(hFile) && fileProgress < fileSize) - { - size_t size = min(chunkSize, fileSize - fileProgress); - if (fread(data, sizeof(uint8_t), size, hFile) == size) - { - tox_file_send_data(tox, number, transfer->number, data, size); - transfer->pfts.totalProgress = transfer->pfts.currentFileProgress = fileProgress += size; - - ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)transfer->number, (LPARAM)&transfer->pfts); - } - } - mir_free(data); - tox_file_send_control(tox, number, 0, transfer->number, TOX_FILECONTROL_FINISHED, NULL, 0); - } - else +void CToxProto::RemoveFromTransferList(FileTransferParam *transfer) +{ + if (transfers.find(transfer->number) != transfers.end()) { - ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer->number, 0); transfers.erase(transfer->number); + delete transfer; } } +/* FILE RECEIVING */ + +// incoming file flow +// send it through miranda void CToxProto::OnFriendFile(Tox *tox, int32_t number, uint8_t fileNumber, uint64_t fileSize, const uint8_t *fileName, uint16_t length, void *arg) { CToxProto *proto = (CToxProto*)arg; @@ -54,7 +31,7 @@ void CToxProto::OnFriendFile(Tox *tox, int32_t number, uint8_t fileNumber, uint6 FileTransferParam *transfer = new FileTransferParam(fileNumber, ptrT(mir_utf8decodeT((const char*)fileName)), fileSize); transfer->pfts.hContact = hContact; transfer->pfts.flags |= PFTS_RECEIVING; - proto->transfers[fileNumber] = transfer; + proto->AddToTransferList(transfer); PROTORECVFILET pre = { 0 }; pre.flags = PREF_TCHAR; @@ -64,11 +41,78 @@ void CToxProto::OnFriendFile(Tox *tox, int32_t number, uint8_t fileNumber, uint6 pre.ptszFiles = (TCHAR**)mir_alloc(sizeof(TCHAR*)* 2); pre.ptszFiles[0] = mir_utf8decodeT((char*)fileName); pre.ptszFiles[1] = NULL; - pre.lParam = (LPARAM)fileNumber; + pre.lParam = (LPARAM)transfer; ProtoChainRecvFile(hContact, &pre); } } +// file request is allowed +HANDLE __cdecl CToxProto::FileAllow(MCONTACT hContact, HANDLE hTransfer, const PROTOCHAR* tszPath) +{ + std::string toxId(getStringA(hContact, TOX_SETTINGS_ID)); + std::vector clientId = HexStringToData(toxId); + + uint32_t number = tox_get_friend_number(tox, clientId.data()); + + FileTransferParam *transfer = (FileTransferParam*)hTransfer; + transfer->pfts.tszWorkingDir = mir_tstrdup(tszPath); + + // stupid fix + //TCHAR fullPath[MAX_PATH]; + //mir_sntprintf(fullPath, SIZEOF(fullPath), _T("%s\\%s"), transfer->pfts.tszWorkingDir, transfer->pfts.tszCurrentFile); + //replaceStrT(transfer->pfts.tszCurrentFile, fullPath); + + //if (!ProtoBroadcastAck(hContact, ACKTYPE_FILE, ACKRESULT_FILERESUME, (HANDLE)transfer, (LPARAM)&transfer->pfts)) + { + tox_file_send_control(tox, number, 1, transfer->number, TOX_FILECONTROL_ACCEPT, NULL, 0); + } + + return hTransfer; +} + +// file request is denied +int __cdecl CToxProto::FileCancel(MCONTACT hContact, HANDLE hTransfer) +{ + std::string toxId(getStringA(hContact, TOX_SETTINGS_ID)); + std::vector clientId = HexStringToData(toxId); + + uint32_t number = tox_get_friend_number(tox, clientId.data()); + + FileTransferParam *transfer = (FileTransferParam*)hTransfer; + RemoveFromTransferList(transfer); + + tox_file_send_control(tox, number, 1, transfer->number, TOX_FILECONTROL_KILL, NULL, 0); + + return 0; +} + +// file request is denied +int __cdecl CToxProto::FileDeny(MCONTACT hContact, HANDLE hTransfer, const PROTOCHAR*) +{ + return FileCancel(hContact, hTransfer); +} + +// some file request stuff +int __cdecl CToxProto::FileResume(HANDLE hTransfer, int* action, const PROTOCHAR** szFilename) +{ + uint8_t fileNumber = (uint8_t)hTransfer; + FileTransferParam *transfer = transfers.at(fileNumber); + + switch (*action) + { + case FILERESUME_RESUME: + //replaceStrT(ft->std.tszCurrentFile, *szFilename); + break; + + case FILERESUME_RENAME: + replaceStrT(transfer->pfts.tszCurrentFile, *szFilename); + break; + } + + return 0; +} + +// getting the file data void CToxProto::OnFileData(Tox *tox, int32_t number, uint8_t fileNumber, const uint8_t *data, uint16_t size, void *arg) { CToxProto *proto = (CToxProto*)arg; @@ -85,7 +129,7 @@ void CToxProto::OnFileData(Tox *tox, int32_t number, uint8_t fileNumber, const u if (transfer->pfts.currentFileProgress == 0) { hFile = _tfopen(filePath, _T("wb+")); - proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)fileNumber, 0); + proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)transfer, 0); } else { @@ -93,18 +137,104 @@ void CToxProto::OnFileData(Tox *tox, int32_t number, uint8_t fileNumber, const u } if (hFile != NULL) { - fseek(hFile, transfer->pfts.currentFileProgress + 1, SEEK_SET); if (fwrite(data, sizeof(uint8_t), size, hFile) == size) { transfer->pfts.totalProgress = transfer->pfts.currentFileProgress += size; - proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)fileNumber, (LPARAM)&transfer->pfts); + proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)transfer, (LPARAM)&transfer->pfts); } fclose(hFile); } } } -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) +/* FILE SENDING */ + +// outcoming file flow +// send request through tox +HANDLE __cdecl CToxProto::SendFile(MCONTACT hContact, const PROTOCHAR* szDescription, PROTOCHAR** ppszFiles) +{ + std::string toxId(getStringA(hContact, TOX_SETTINGS_ID)); + std::vector clientId = HexStringToData(toxId); + + uint32_t number = tox_get_friend_number(tox, clientId.data()); + + TCHAR *fileName = _tcsrchr(ppszFiles[0], '\\') + 1; + + size_t fileDirLength = fileName - ppszFiles[0]; + TCHAR *fileDir = (TCHAR*)mir_alloc(sizeof(TCHAR)*fileDirLength); + _tcsncpy(fileDir, ppszFiles[0], fileDirLength); + fileDir[fileDirLength] = '\0'; + + size_t fileSize = 0; + FILE *file = _tfopen(ppszFiles[0], _T("rb")); + if (file != NULL) + { + fseek(file, 0, SEEK_END); + fileSize = ftell(file); + fseek(file, 0, SEEK_SET); + fclose(file); + } + + int fileNumber = tox_new_file_sender(tox, number, fileSize, (uint8_t*)(char*)ptrA(mir_utf8encodeT(fileName)), _tcslen(fileName)); + if (fileNumber < 0) + { + debugLogA("CToxProto::SendFilesAsync: cannot send file"); + return NULL; + } + + FileTransferParam *transfer = new FileTransferParam(fileNumber, fileName, fileSize); + transfer->pfts.hContact = hContact; + transfer->pfts.flags |= PFTS_RECEIVING; + transfer->pfts.tszWorkingDir = fileDir; + AddToTransferList(transfer); + + return (HANDLE)transfer; +} + +// start sending +void CToxProto::SendFileAsync(void* arg) +{ + FileTransferParam *transfer = (FileTransferParam*)arg; + + std::string toxId(getStringA(transfer->pfts.hContact, TOX_SETTINGS_ID)); + std::vector clientId = HexStringToData(toxId); + + if (uint32_t number = tox_get_friend_number(tox, clientId.data()) > TOX_ERROR) + { + size_t fileSize = transfer->pfts.currentFileSize; + size_t fileProgress = 0; + TCHAR filePath[MAX_PATH]; + mir_sntprintf(filePath, SIZEOF(filePath), _T("%s%s"), transfer->pfts.tszWorkingDir, transfer->pfts.tszCurrentFile); + + FILE *hFile = _wfopen(filePath, _T("rb")); + if (!hFile) + { + ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0); + RemoveFromTransferList(transfer); + return; + } + + size_t chunkSize = min(tox_file_data_size(tox, number), fileSize); + uint8_t *data = (uint8_t*)mir_alloc(chunkSize); + while (!feof(hFile) && fileProgress < fileSize) + { + size_t size = min(chunkSize, fileSize - fileProgress); + if (fread(data, sizeof(uint8_t), size, hFile) == size) + { + tox_file_send_data(tox, number, transfer->number, data, size); + transfer->pfts.totalProgress = transfer->pfts.currentFileProgress = fileProgress += size; + + ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)transfer, (LPARAM)&transfer->pfts); + } + } + mir_free(data); + tox_file_send_control(tox, number, 0, transfer->number, TOX_FILECONTROL_FINISHED, NULL, 0); + } +} + +/* GENERAL */ + +void CToxProto::OnFileRequest(Tox *tox, int32_t number, uint8_t receive_send, uint8_t fileNumber, uint8_t type, const uint8_t *data, uint16_t length, void *arg) { CToxProto *proto = (CToxProto*)arg; @@ -115,15 +245,27 @@ void CToxProto::OnFileRequest(Tox *tox, int32_t number, uint8_t isSend, uint8_t switch (type) { + // if friend allow file request case TOX_FILECONTROL_ACCEPT: proto->ForkThread(&CToxProto::SendFileAsync, transfer); - proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)fileNumber, 0); + proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)transfer, 0); + break; + + // if file transfer is paused + case TOX_FILECONTROL_PAUSE: + proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FILERESUME, (HANDLE)transfer, 0); + break; + + // if file transfer is cancelled + case TOX_FILECONTROL_KILL: + proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)transfer, 0); break; + // if file transfer is finished case TOX_FILECONTROL_FINISHED: tox_file_send_control(proto->tox, number, 1, fileNumber, TOX_FILECONTROL_FINISHED, NULL, 0); - proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, (HANDLE)fileNumber, 0); - proto->transfers.erase(fileNumber); + proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, (HANDLE)transfer, 0); + proto->RemoveFromTransferList(transfer); break; } } -- cgit v1.2.3