diff options
Diffstat (limited to 'protocols/Tox/src')
-rw-r--r-- | protocols/Tox/src/common.h | 1 | ||||
-rw-r--r-- | protocols/Tox/src/file_transfer.h | 151 | ||||
-rw-r--r-- | protocols/Tox/src/tox/tox.h | 5 | ||||
-rw-r--r-- | protocols/Tox/src/tox_account.cpp | 11 | ||||
-rw-r--r-- | protocols/Tox/src/tox_bootstrap.h | 2 | ||||
-rw-r--r-- | protocols/Tox/src/tox_contacts.cpp | 6 | ||||
-rw-r--r-- | protocols/Tox/src/tox_events.cpp | 12 | ||||
-rw-r--r-- | protocols/Tox/src/tox_proto.cpp | 24 | ||||
-rw-r--r-- | protocols/Tox/src/tox_proto.h | 11 | ||||
-rw-r--r-- | protocols/Tox/src/tox_transfers.cpp | 27 |
10 files changed, 227 insertions, 23 deletions
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<CFile> 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<CToxProto>(protoName, userName)
+ PROTO<CToxProto>(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<CToxProto>
{
@@ -75,6 +75,8 @@ private: bool isTerminated;
bool isConnected;
HANDLE hNetlibUser;
+ ULONG hFileProcess;
+ LIST<CFile> 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<uint8_t> 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 |