summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--protocols/Tox/src/common.h2
-rw-r--r--protocols/Tox/src/tox_contacts.cpp3
-rw-r--r--protocols/Tox/src/tox_proto.cpp105
-rw-r--r--protocols/Tox/src/tox_proto.h5
-rw-r--r--protocols/Tox/src/tox_transfer.cpp230
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<uint8_t> 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<uint8_t> 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<uint8_t> 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<uint8_t> 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<uint8_t> 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<uint8_t> 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<uint8_t> 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<uint8_t> 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;
}
}