From ce49c84f3a26f016f9232d2bffdc830d7fd6169f Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Sat, 30 Aug 2014 11:37:47 +0000 Subject: Tox: - switch to offline when connection is lost - file transfer support - code refactoring - project reordering - version bump git-svn-id: http://svn.miranda-ng.org/main/trunk@10340 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Tox/src/common.h | 3 +- protocols/Tox/src/file_transfer.h | 197 ----------- protocols/Tox/src/main.cpp | 4 +- protocols/Tox/src/stdafx.cpp | 18 - protocols/Tox/src/tox/tox.h | 683 ------------------------------------ protocols/Tox/src/tox/toxav.h | 389 -------------------- protocols/Tox/src/tox/toxdns.h | 85 ----- protocols/Tox/src/tox_account.cpp | 45 ++- protocols/Tox/src/tox_accounts.cpp | 43 +++ protocols/Tox/src/tox_contacts.cpp | 128 ++++--- protocols/Tox/src/tox_events.cpp | 274 --------------- protocols/Tox/src/tox_instances.cpp | 44 --- protocols/Tox/src/tox_messages.cpp | 83 +++++ protocols/Tox/src/tox_netlib.cpp | 6 +- protocols/Tox/src/tox_options.cpp | 100 ------ protocols/Tox/src/tox_profile.cpp | 79 +++++ protocols/Tox/src/tox_proto.cpp | 90 ++++- protocols/Tox/src/tox_proto.h | 111 +++--- protocols/Tox/src/tox_search.cpp | 79 +++++ protocols/Tox/src/tox_services.cpp | 2 - protocols/Tox/src/tox_transfer.cpp | 128 +++++++ protocols/Tox/src/tox_transfers.cpp | 44 --- protocols/Tox/src/tox_utils.cpp | 26 -- protocols/Tox/src/version.h | 2 +- 24 files changed, 660 insertions(+), 2003 deletions(-) delete mode 100644 protocols/Tox/src/file_transfer.h delete mode 100644 protocols/Tox/src/stdafx.cpp delete mode 100644 protocols/Tox/src/tox/tox.h delete mode 100644 protocols/Tox/src/tox/toxav.h delete mode 100644 protocols/Tox/src/tox/toxdns.h create mode 100644 protocols/Tox/src/tox_accounts.cpp delete mode 100644 protocols/Tox/src/tox_instances.cpp create mode 100644 protocols/Tox/src/tox_messages.cpp create mode 100644 protocols/Tox/src/tox_profile.cpp create mode 100644 protocols/Tox/src/tox_search.cpp delete mode 100644 protocols/Tox/src/tox_services.cpp create mode 100644 protocols/Tox/src/tox_transfer.cpp delete 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 bb417850ca..e7fd4ce733 100644 --- a/protocols/Tox/src/common.h +++ b/protocols/Tox/src/common.h @@ -29,12 +29,11 @@ #include #include -#include "tox\tox.h" +#include #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 deleted file mode 100644 index 6f30b90241..0000000000 --- a/protocols/Tox/src/file_transfer.h +++ /dev/null @@ -1,197 +0,0 @@ -#ifndef _FILE_TRANSFER_H_ -#define _FILE_TRANSFER_H_ - -class CFileTransfer; - -class CFile -{ -private: - int number; - char *name; - const TCHAR *path; - size_t size; - - const CFileTransfer *transfer; - -public: - CFile(const CFileTransfer *fileTransfer, const TCHAR *filePath, size_t fileSize) : - number(-1) - { - transfer = fileTransfer; - - path = filePath; - name = strrchr(ptrA(mir_utf8encodeT(path)), '\\'); - size = fileSize; - } - - CFile(int number) : number(number), name(NULL) { } - - ~CFile() - { - number = -1; - if (name != NULL) - { - mir_free(name); - } - } - - const CFileTransfer *GetTransfer() const - { - return this->transfer; - } - - void SetNumber(int fileNumber) - { - number = fileNumber; - } - - const TCHAR* GetPath() const - { - return path; - } - - const char* GetName() const - { - return name; - } - - size_t GetSize() const - { - return size; - } -}; - -class CFileTransfer -{ -private: - ULONG number; - - HANDLE hWait; - LIST files; - PROTOFILETRANSFERSTATUS pfts; - const PROTO_INTERFACE *proto; - -public: - CFileTransfer(const PROTO_INTERFACE *proto, MCONTACT hContact, ULONG transferNumber, DWORD flags) : - files(1, NumericKeySortT) - { - this->proto = proto; - - 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; - - number = transferNumber; - } - - ~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, ppszFiles[i], fileSize)); - } - } - - const PROTO_INTERFACE *GetProtoInstance() const - { - return proto; - } - - ULONG GetTransferNumber() const - { - return number; - } - - MCONTACT GetContactHandle() const - { - return pfts.hContact; - } - - int GetFileCount() const - { - return pfts.totalFiles; - } - - CFile *GetFileAt(int idx) const - { - return files[idx]; - } - - CFile *GetFileByNumber(int number) const - { - CFile *search = new CFile(number); - CFile *file = files.find(search); - delete search; - - return file; - } - - bool HasFile(int number) const - { - const CFile *file = GetFileByNumber(number); - - return file != NULL; - } - - void Wait() - { - WaitForSingleObject(hWait, INFINITE); - } -}; - -class CFileSendTransfer : public CFileTransfer -{ -public: - CFileSendTransfer(MCONTACT hContact, ULONG hProcess) : CFileTransfer(NULL, hContact, hProcess, PFTS_SENDING) - { - } -}; - -#endif //_FILE_TRANSFER_H_ \ No newline at end of file diff --git a/protocols/Tox/src/main.cpp b/protocols/Tox/src/main.cpp index f9322d7f3e..dcf36ddbb6 100644 --- a/protocols/Tox/src/main.cpp +++ b/protocols/Tox/src/main.cpp @@ -39,8 +39,8 @@ extern "C" int __declspec(dllexport) Load(void) PROTOCOLDESCRIPTOR pd = { sizeof(pd) }; pd.szName = "TOX"; pd.type = PROTOTYPE_PROTOCOL; - pd.fnInit = (pfnInitProto)CToxProto::InitProtoInstance; - pd.fnUninit = (pfnUninitProto)CToxProto::UninitProtoInstance; + pd.fnInit = (pfnInitProto)CToxProto::InitAccount; + pd.fnUninit = (pfnUninitProto)CToxProto::UninitAccount; CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM)&pd); return 0; diff --git a/protocols/Tox/src/stdafx.cpp b/protocols/Tox/src/stdafx.cpp deleted file mode 100644 index 7d92b0fd29..0000000000 --- a/protocols/Tox/src/stdafx.cpp +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright (c) 2013-14 Miranda NG project (http://miranda-ng.org) - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation version 2 -of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "common.h" diff --git a/protocols/Tox/src/tox/tox.h b/protocols/Tox/src/tox/tox.h deleted file mode 100644 index 5810c1289c..0000000000 --- a/protocols/Tox/src/tox/tox.h +++ /dev/null @@ -1,683 +0,0 @@ -/* tox.h - * - * The Tox public API. - * - * Copyright (C) 2013 Tox project All Rights Reserved. - * - * This file is part of Tox. - * - * Tox is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tox. If not, see . - * - */ - -#ifndef TOX_H -#define TOX_H - -#include - - -#ifdef __cplusplus -extern "C" { -#endif - -#define TOX_MAX_NAME_LENGTH 128 - -/* Maximum length of single messages after which they should be split. */ -#define TOX_MAX_MESSAGE_LENGTH 1368 -#define TOX_MAX_STATUSMESSAGE_LENGTH 1007 -#define TOX_CLIENT_ID_SIZE 32 - -#define TOX_FRIEND_ADDRESS_SIZE (TOX_CLIENT_ID_SIZE + sizeof(uint32_t) + sizeof(uint16_t)) - -#define TOX_ENABLE_IPV6_DEFAULT 1 - -/* Errors for m_addfriend - * FAERR - Friend Add Error - */ -enum { - TOX_FAERR_TOOLONG = -1, - TOX_FAERR_NOMESSAGE = -2, - TOX_FAERR_OWNKEY = -3, - TOX_FAERR_ALREADYSENT = -4, - TOX_FAERR_UNKNOWN = -5, - TOX_FAERR_BADCHECKSUM = -6, - TOX_FAERR_SETNEWNOSPAM = -7, - TOX_FAERR_NOMEM = -8 -}; - -/* USERSTATUS - - * Represents userstatuses someone can have. - */ -typedef enum { - TOX_USERSTATUS_NONE, - TOX_USERSTATUS_AWAY, - TOX_USERSTATUS_BUSY, - TOX_USERSTATUS_INVALID -} -TOX_USERSTATUS; - -#ifndef __TOX_DEFINED__ -#define __TOX_DEFINED__ -typedef struct Tox Tox; -#endif - -/* NOTE: Strings in Tox are all UTF-8, (This means that there is no terminating NULL character.) - * - * The exact buffer you send will be received at the other end without modification. - * - * Do not treat Tox strings as C strings. - */ - -/* return TOX_FRIEND_ADDRESS_SIZE byte address to give to others. - * format: [client_id (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)] - */ -void tox_get_address(const Tox *tox, uint8_t *address); - -/* Add a friend. - * Set the data that will be sent along with friend request. - * address is the address of the friend (returned by getaddress of the friend you wish to add) it must be TOX_FRIEND_ADDRESS_SIZE bytes. TODO: add checksum. - * data is the data and length is the length. - * - * return the friend number if success. - * return TOX_FAERR_TOOLONG if message length is too long. - * return TOX_FAERR_NOMESSAGE if no message (message length must be >= 1 byte). - * return TOX_FAERR_OWNKEY if user's own key. - * return TOX_FAERR_ALREADYSENT if friend request already sent or already a friend. - * return TOX_FAERR_UNKNOWN for unknown error. - * return TOX_FAERR_BADCHECKSUM if bad checksum in address. - * return TOX_FAERR_SETNEWNOSPAM if the friend was already there but the nospam was different. - * (the nospam for that friend was set to the new one). - * return TOX_FAERR_NOMEM if increasing the friend list size fails. - */ -int32_t tox_add_friend(Tox *tox, const uint8_t *address, const uint8_t *data, uint16_t length); - - -/* Add a friend without sending a friendrequest. - * return the friend number if success. - * return -1 if failure. - */ -int32_t tox_add_friend_norequest(Tox *tox, const uint8_t *client_id); - -/* return the friend number associated to that client id. - return -1 if no such friend */ -int32_t tox_get_friend_number(const Tox *tox, const uint8_t *client_id); - -/* Copies the public key associated to that friend id into client_id buffer. - * Make sure that client_id is of size CLIENT_ID_SIZE. - * return 0 if success. - * return -1 if failure. - */ -int tox_get_client_id(const Tox *tox, int32_t friendnumber, uint8_t *client_id); - -/* Remove a friend. - * - * return 0 if success. - * return -1 if failure. - */ -int tox_del_friend(Tox *tox, int32_t friendnumber); - -/* Checks friend's connecting status. - * - * return 1 if friend is connected to us (Online). - * return 0 if friend is not connected to us (Offline). - * return -1 on failure. - */ -int tox_get_friend_connection_status(const Tox *tox, int32_t friendnumber); - -/* Checks if there exists a friend with given friendnumber. - * - * return 1 if friend exists. - * return 0 if friend doesn't exist. - */ -int tox_friend_exists(const Tox *tox, int32_t friendnumber); - -/* Send a text chat message to an online friend. - * - * return the message id if packet was successfully put into the send queue. - * return 0 if it was not. - * - * maximum length of messages is TOX_MAX_MESSAGE_LENGTH, your client must split larger messages - * or else sending them will not work. No the core will not split messages for you because that - * requires me to parse UTF-8. - * - * You will want to retain the return value, it will be passed to your read_receipt callback - * if one is received. - * m_sendmessage_withid will send a message with the id of your choosing, - * however we can generate an id for you by calling plain m_sendmessage. - */ -uint32_t tox_send_message(Tox *tox, int32_t friendnumber, const uint8_t *message, uint32_t length); -uint32_t tox_send_message_withid(Tox *tox, int32_t friendnumber, uint32_t theid, const uint8_t *message, - uint32_t length); - -/* Send an action to an online friend. - * - * return the message id if packet was successfully put into the send queue. - * return 0 if it was not. - * - * maximum length of actions is TOX_MAX_MESSAGE_LENGTH, your client must split larger actions - * or else sending them will not work. No the core will not split actions for you because that - * requires me to parse UTF-8. - * - * You will want to retain the return value, it will be passed to your read_receipt callback - * if one is received. - * m_sendaction_withid will send an action message with the id of your choosing, - * however we can generate an id for you by calling plain m_sendaction. - */ -uint32_t tox_send_action(Tox *tox, int32_t friendnumber, const uint8_t *action, uint32_t length); -uint32_t tox_send_action_withid(Tox *tox, int32_t friendnumber, uint32_t theid, const uint8_t *action, uint32_t length); - -/* Set our nickname. - * name must be a string of maximum MAX_NAME_LENGTH length. - * length must be at least 1 byte. - * length is the length of name with the NULL terminator. - * - * return 0 if success. - * return -1 if failure. - */ -int tox_set_name(Tox *tox, const uint8_t *name, uint16_t length); - -/* - * Get your nickname. - * m - The messenger context to use. - * name - needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes. - * - * return length of name. - * return 0 on error. - */ -uint16_t tox_get_self_name(const Tox *tox, uint8_t *name); - -/* Get name of friendnumber and put it in name. - * name needs to be a valid memory location with a size of at least MAX_NAME_LENGTH (128) bytes. - * - * return length of name if success. - * return -1 if failure. - */ -int tox_get_name(const Tox *tox, int32_t friendnumber, uint8_t *name); - -/* returns the length of name on success. - * returns -1 on failure. - */ -int tox_get_name_size(const Tox *tox, int32_t friendnumber); -int tox_get_self_name_size(const Tox *tox); - -/* Set our user status. - * - * userstatus must be one of TOX_USERSTATUS values. - * max length of the status is TOX_MAX_STATUSMESSAGE_LENGTH. - * - * returns 0 on success. - * returns -1 on failure. - */ -int tox_set_status_message(Tox *tox, const uint8_t *status, uint16_t length); -int tox_set_user_status(Tox *tox, uint8_t userstatus); - -/* returns the length of status message on success. - * returns -1 on failure. - */ -int tox_get_status_message_size(const Tox *tox, int32_t friendnumber); -int tox_get_self_status_message_size(const Tox *tox); - -/* Copy friendnumber's status message into buf, truncating if size is over maxlen. - * Get the size you need to allocate from m_get_statusmessage_size. - * The self variant will copy our own status message. - * - * returns the length of the copied data on success - * retruns -1 on failure. - */ -int tox_get_status_message(const Tox *tox, int32_t friendnumber, uint8_t *buf, uint32_t maxlen); -int tox_get_self_status_message(const Tox *tox, uint8_t *buf, uint32_t maxlen); - -/* return one of TOX_USERSTATUS values. - * Values unknown to your application should be represented as TOX_USERSTATUS_NONE. - * As above, the self variant will return our own TOX_USERSTATUS. - * If friendnumber is invalid, this shall return TOX_USERSTATUS_INVALID. - */ -uint8_t tox_get_user_status(const Tox *tox, int32_t friendnumber); -uint8_t tox_get_self_user_status(const Tox *tox); - - -/* returns timestamp of last time friendnumber was seen online, or 0 if never seen. - * returns -1 on error. - */ -uint64_t tox_get_last_online(const Tox *tox, int32_t friendnumber); - -/* Set our typing status for a friend. - * You are responsible for turning it on or off. - * - * returns 0 on success. - * returns -1 on failure. - */ -int tox_set_user_is_typing(Tox *tox, int32_t friendnumber, uint8_t is_typing); - -/* Get the typing status of a friend. - * - * returns 0 if friend is not typing. - * returns 1 if friend is typing. - */ -uint8_t tox_get_is_typing(const Tox *tox, int32_t friendnumber); - -/* Return the number of friends in the instance m. - * You should use this to determine how much memory to allocate - * for copy_friendlist. */ -uint32_t tox_count_friendlist(const Tox *tox); - -/* Return the number of online friends in the instance m. */ -uint32_t tox_get_num_online_friends(const Tox *tox); - -/* Copy a list of valid friend IDs into the array out_list. - * If out_list is NULL, returns 0. - * Otherwise, returns the number of elements copied. - * If the array was too small, the contents - * of out_list will be truncated to list_size. */ -uint32_t tox_get_friendlist(const Tox *tox, int32_t *out_list, uint32_t list_size); - -/* Set the function that will be executed when a friend request is received. - * Function format is function(Tox *tox, uint8_t * public_key, uint8_t * data, uint16_t length, void *userdata) - */ -void tox_callback_friend_request(Tox *tox, void (*function)(Tox *tox, const uint8_t *, const uint8_t *, uint16_t, - void *), void *userdata); - -/* Set the function that will be executed when a message from a friend is received. - * Function format is: function(Tox *tox, int32_t friendnumber, uint8_t * message, uint16_t length, void *userdata) - */ -void tox_callback_friend_message(Tox *tox, void (*function)(Tox *tox, int32_t, const uint8_t *, uint16_t, void *), - void *userdata); - -/* Set the function that will be executed when an action from a friend is received. - * Function format is: function(Tox *tox, int32_t friendnumber, uint8_t * action, uint16_t length, void *userdata) - */ -void tox_callback_friend_action(Tox *tox, void (*function)(Tox *tox, int32_t, const uint8_t *, uint16_t, void *), - void *userdata); - -/* Set the callback for name changes. - * function(Tox *tox, int32_t friendnumber, uint8_t *newname, uint16_t length, void *userdata) - * You are not responsible for freeing newname - */ -void tox_callback_name_change(Tox *tox, void (*function)(Tox *tox, int32_t, const uint8_t *, uint16_t, void *), - void *userdata); - -/* Set the callback for status message changes. - * function(Tox *tox, int32_t friendnumber, uint8_t *newstatus, uint16_t length, void *userdata) - * You are not responsible for freeing newstatus. - */ -void tox_callback_status_message(Tox *tox, void (*function)(Tox *tox, int32_t, const uint8_t *, uint16_t, void *), - void *userdata); - -/* Set the callback for status type changes. - * function(Tox *tox, int32_t friendnumber, uint8_t TOX_USERSTATUS, void *userdata) - */ -void tox_callback_user_status(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t, void *), void *userdata); - -/* Set the callback for typing changes. - * function (Tox *tox, int32_t friendnumber, uint8_t is_typing, void *userdata) - */ -void tox_callback_typing_change(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t, void *), void *userdata); - -/* Set the callback for read receipts. - * function(Tox *tox, int32_t friendnumber, uint32_t receipt, void *userdata) - * - * If you are keeping a record of returns from m_sendmessage; - * receipt might be one of those values, meaning the message - * has been received on the other side. - * Since core doesn't track ids for you, receipt may not correspond to any message. - * In that case, you should discard it. - */ -void tox_callback_read_receipt(Tox *tox, void (*function)(Tox *tox, int32_t, uint32_t, void *), void *userdata); - -/* Set the callback for connection status changes. - * function(Tox *tox, int32_t friendnumber, uint8_t status, void *userdata) - * - * Status: - * 0 -- friend went offline after being previously online - * 1 -- friend went online - * - * NOTE: This callback is not called when adding friends, thus the "after - * being previously online" part. it's assumed that when adding friends, - * their connection status is offline. - */ -void tox_callback_connection_status(Tox *tox, void (*function)(Tox *tox, int32_t, uint8_t, void *), void *userdata); - - -/**********ADVANCED FUNCTIONS (If you don't know what they do you can safely ignore them.) ************/ - -/* Functions to get/set the nospam part of the id. - */ -uint32_t tox_get_nospam(const Tox *tox); -void tox_set_nospam(Tox *tox, uint32_t nospam); - -/* Copy the public and secret key from the Tox object. - public_key and secret_key must be 32 bytes big. - if the pointer is NULL, no data will be copied to it.*/ -void tox_get_keys(Tox *tox, uint8_t *public_key, uint8_t *secret_key); - -/**********GROUP CHAT FUNCTIONS: WARNING Group chats will be rewritten so this might change ************/ - -/* Set the callback for group invites. - * - * Function(Tox *tox, int friendnumber, uint8_t *group_public_key, void *userdata) - */ -void tox_callback_group_invite(Tox *tox, void (*function)(Tox *tox, int32_t, const uint8_t *, void *), void *userdata); - -/* Set the callback for group messages. - * - * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * message, uint16_t length, void *userdata) - */ -void tox_callback_group_message(Tox *tox, void (*function)(Tox *tox, int, int, const uint8_t *, uint16_t, void *), - void *userdata); - -/* Set the callback for group actions. - * - * Function(Tox *tox, int groupnumber, int friendgroupnumber, uint8_t * action, uint16_t length, void *userdata) - */ -void tox_callback_group_action(Tox *tox, void (*function)(Tox *tox, int, int, const uint8_t *, uint16_t, void *), - void *userdata); - -/* Set callback function for peer name list changes. - * - * It gets called every time the name list changes(new peer/name, deleted peer) - * Function(Tox *tox, int groupnumber, int peernumber, TOX_CHAT_CHANGE change, void *userdata) - */ -typedef enum { - TOX_CHAT_CHANGE_PEER_ADD, - TOX_CHAT_CHANGE_PEER_DEL, - TOX_CHAT_CHANGE_PEER_NAME, -} TOX_CHAT_CHANGE; - -void tox_callback_group_namelist_change(Tox *tox, void (*function)(Tox *tox, int, int, uint8_t, void *), - void *userdata); - -/* Creates a new groupchat and puts it in the chats array. - * - * return group number on success. - * return -1 on failure. - */ -int tox_add_groupchat(Tox *tox); - -/* Delete a groupchat from the chats array. - * - * return 0 on success. - * return -1 if failure. - */ -int tox_del_groupchat(Tox *tox, int groupnumber); - -/* Copy the name of peernumber who is in groupnumber to name. - * name must be at least TOX_MAX_NAME_LENGTH long. - * - * return length of name if success - * return -1 if failure - */ -int tox_group_peername(const Tox *tox, int groupnumber, int peernumber, uint8_t *name); - -/* invite friendnumber to groupnumber - * return 0 on success - * return -1 on failure - */ -int tox_invite_friend(Tox *tox, int32_t friendnumber, int groupnumber); - -/* Join a group (you need to have been invited first.) - * - * returns group number on success - * returns -1 on failure. - */ -int tox_join_groupchat(Tox *tox, int32_t friendnumber, const uint8_t *friend_group_public_key); - -/* send a group message - * return 0 on success - * return -1 on failure - */ -int tox_group_message_send(Tox *tox, int groupnumber, const uint8_t *message, uint32_t length); - -/* send a group action - * return 0 on success - * return -1 on failure - */ -int tox_group_action_send(Tox *tox, int groupnumber, const uint8_t *action, uint32_t length); - -/* Return the number of peers in the group chat on success. - * return -1 on failure - */ -int tox_group_number_peers(const Tox *tox, int groupnumber); - -/* List all the peers in the group chat. - * - * Copies the names of the peers to the name[length][TOX_MAX_NAME_LENGTH] array. - * - * Copies the lengths of the names to lengths[length] - * - * returns the number of peers on success. - * - * return -1 on failure. - */ -int tox_group_get_names(const Tox *tox, int groupnumber, uint8_t names[][TOX_MAX_NAME_LENGTH], uint16_t lengths[], - uint16_t length); - -/* Return the number of chats in the instance m. - * You should use this to determine how much memory to allocate - * for copy_chatlist. */ -uint32_t tox_count_chatlist(const Tox *tox); - -/* Copy a list of valid chat IDs into the array out_list. - * If out_list is NULL, returns 0. - * Otherwise, returns the number of elements copied. - * If the array was too small, the contents - * of out_list will be truncated to list_size. */ -uint32_t tox_get_chatlist(const Tox *tox, int *out_list, uint32_t list_size); - - -/****************FILE SENDING FUNCTIONS*****************/ -/* NOTE: This how to will be updated. - * - * HOW TO SEND FILES CORRECTLY: - * 1. Use tox_new_file_sender(...) to create a new file sender. - * 2. Wait for the callback set with tox_callback_file_control(...) to be called with receive_send == 1 and control_type == TOX_FILECONTROL_ACCEPT - * 3. Send the data with tox_file_send_data(...) with chunk size tox_file_data_size(...) - * 4. When sending is done, send a tox_file_send_control(...) with send_receive = 0 and message_id = TOX_FILECONTROL_FINISHED - * 5. when the callback set with tox_callback_file_control(...) is called with receive_send == 1 and control_type == TOX_FILECONTROL_FINISHED - * the other person has received the file correctly. - * - * HOW TO RECEIVE FILES CORRECTLY: - * 1. wait for the callback set with tox_callback_file_send_request(...) - * 2. accept or refuse the connection with tox_file_send_control(...) with send_receive = 1 and message_id = TOX_FILECONTROL_ACCEPT or TOX_FILECONTROL_KILL - * 3. save all the data received with the callback set with tox_callback_file_data(...) to a file. - * 4. when the callback set with tox_callback_file_control(...) is called with receive_send == 0 and control_type == TOX_FILECONTROL_FINISHED - * the file is done transferring. - * 5. send a tox_file_send_control(...) with send_receive = 1 and message_id = TOX_FILECONTROL_FINISHED to confirm that we did receive the file. - * - * tox_file_data_remaining(...) can be used to know how many bytes are left to send/receive. - * - * If the connection breaks during file sending (The other person goes offline without pausing the sending and then comes back) - * the receiver must send a control packet with send_receive == 1 message_id = TOX_FILECONTROL_RESUME_BROKEN and the data being - * a uint64_t (in host byte order) containing the number of bytes received. - * - * If the sender receives this packet, he must send a control packet with send_receive == 0 and control_type == TOX_FILECONTROL_ACCEPT - * then he must start sending file data from the position (data , uint64_t in host byte order) received in the TOX_FILECONTROL_RESUME_BROKEN packet. - * - * To pause a file transfer send a control packet with control_type == TOX_FILECONTROL_PAUSE. - * To unpause a file transfer send a control packet with control_type == TOX_FILECONTROL_ACCEPT. - * - * If you receive a control packet with receive_send == 1 and control_type == TOX_FILECONTROL_PAUSE, you must stop sending filenumber until the other - * person sends a control packet with send_receive == 0 and control_type == TOX_FILECONTROL_ACCEPT with the filenumber being a paused filenumber. - * - * If you receive a control packet with receive_send == 0 and control_type == TOX_FILECONTROL_PAUSE, it means the sender of filenumber has paused the - * transfer and will resume it later with a control packet with send_receive == 1 and control_type == TOX_FILECONTROL_ACCEPT for that file number. - * - * More to come... - */ - -enum { - TOX_FILECONTROL_ACCEPT, - TOX_FILECONTROL_PAUSE, - TOX_FILECONTROL_KILL, - TOX_FILECONTROL_FINISHED, - TOX_FILECONTROL_RESUME_BROKEN -}; -/* Set the callback for file send requests. - * - * Function(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint64_t filesize, uint8_t *filename, uint16_t filename_length, void *userdata) - */ -void tox_callback_file_send_request(Tox *tox, void (*function)(Tox *m, int32_t, uint8_t, uint64_t, const uint8_t *, - uint16_t, void *), void *userdata); - -/* Set the callback for file control requests. - * - * receive_send is 1 if the message is for a slot on which we are currently sending a file and 0 if the message - * is for a slot on which we are receiving the file - * - * Function(Tox *tox, int32_t friendnumber, uint8_t receive_send, uint8_t filenumber, uint8_t control_type, uint8_t *data, uint16_t length, void *userdata) - * - */ -void tox_callback_file_control(Tox *tox, void (*function)(Tox *m, int32_t, uint8_t, uint8_t, uint8_t, const uint8_t *, - uint16_t, void *), void *userdata); - -/* Set the callback for file data. - * - * Function(Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8_t *data, uint16_t length, void *userdata) - * - */ -void tox_callback_file_data(Tox *tox, void (*function)(Tox *m, int32_t, uint8_t, const uint8_t *, uint16_t length, - void *), void *userdata); - - -/* Send a file send request. - * Maximum filename length is 255 bytes. - * return file number on success - * return -1 on failure - */ -int tox_new_file_sender(Tox *tox, int32_t friendnumber, uint64_t filesize, const uint8_t *filename, - uint16_t filename_length); - -/* Send a file control request. - * - * send_receive is 0 if we want the control packet to target a file we are currently sending, - * 1 if it targets a file we are currently receiving. - * - * return 0 on success - * return -1 on failure - */ -int tox_file_send_control(Tox *tox, int32_t friendnumber, uint8_t send_receive, uint8_t filenumber, uint8_t message_id, - const uint8_t *data, uint16_t length); - -/* Send file data. - * - * return 0 on success - * return -1 on failure - */ -int tox_file_send_data(Tox *tox, int32_t friendnumber, uint8_t filenumber, const uint8_t *data, uint16_t length); - -/* Returns the recommended/maximum size of the filedata you send with tox_file_send_data() - * - * return size on success - * return -1 on failure (currently will never return -1) - */ -int tox_file_data_size(const Tox *tox, int32_t friendnumber); - -/* Give the number of bytes left to be sent/received. - * - * send_receive is 0 if we want the sending files, 1 if we want the receiving. - * - * return number of bytes remaining to be sent/received on success - * return 0 on failure - */ -uint64_t tox_file_data_remaining(const Tox *tox, int32_t friendnumber, uint8_t filenumber, uint8_t send_receive); - -/***************END OF FILE SENDING FUNCTIONS******************/ - -/* - * Use this function to bootstrap the client. - */ - -/* Resolves address into an IP address. If successful, sends a "get nodes" - * request to the given node with ip, port (in host byte order). - * and public_key to setup connections - * - * address can be a hostname or an IP address (IPv4 or IPv6). - * - * returns 1 if the address could be converted into an IP address - * returns 0 otherwise - */ -int tox_bootstrap_from_address(Tox *tox, const char *address, uint16_t port, const uint8_t *public_key); - -/* return 0 if we are not connected to the DHT. - * return 1 if we are. - */ -int tox_isconnected(const Tox *tox); - -typedef struct { - /* - * The type of UDP socket created depends on ipv6enabled: - * If set to 0 (zero), creates an IPv4 socket which subsequently only allows - * IPv4 communication - * If set to anything else (default), creates an IPv6 socket which allows both IPv4 AND - * IPv6 communication - */ - uint8_t ipv6enabled; - - /* Set to 1 to disable udp support. (default: 0) - This will force Tox to use TCP only which may slow things down. - Disabling udp support is necessary when using anonymous proxies or Tor.*/ - uint8_t udp_disabled; - - /* Enable proxy support. (only basic TCP socks5 proxy currently supported.) (default: 0 (disabled))*/ - uint8_t proxy_enabled; - char proxy_address[256]; /* Proxy ip or domain in NULL terminated string format. */ - uint16_t proxy_port; /* Proxy port: in host byte order. */ -} Tox_Options; - -/* - * Run this function at startup. - * - * Options are some options that can be passed to the Tox instance (see above struct). - * - * If options is NULL, tox_new() will use default settings. - * - * Initializes a tox structure - * return allocated instance of tox on success. - * return NULL on failure. - */ -Tox *tox_new(Tox_Options *options); - -/* Run this before closing shop. - * Free all datastructures. */ -void tox_kill(Tox *tox); - -/* Return the time in milliseconds before tox_do() should be called again - * for optimal performance. - * - * returns time (in ms) before the next tox_do() needs to be run on success. - */ -uint32_t tox_do_interval(Tox *tox); - -/* The main loop that needs to be run in intervals of tox_do_interval() ms. */ -void tox_do(Tox *tox); - -/* SAVING AND LOADING FUNCTIONS: */ - -/* return size of messenger data (for saving). */ -uint32_t tox_size(const Tox *tox); - -/* Save the messenger in data (must be allocated memory of size Messenger_size()). */ -void tox_save(const Tox *tox, uint8_t *data); - -/* Load the messenger from data of size length. - * - * returns 0 on success - * returns -1 on failure - */ -int tox_load(Tox *tox, const uint8_t *data, uint32_t length); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/protocols/Tox/src/tox/toxav.h b/protocols/Tox/src/tox/toxav.h deleted file mode 100644 index e31c7aad1f..0000000000 --- a/protocols/Tox/src/tox/toxav.h +++ /dev/null @@ -1,389 +0,0 @@ -/** toxav.h - * - * Copyright (C) 2013 Tox project All Rights Reserved. - * - * This file is part of Tox. - * - * Tox is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tox. If not, see . - * - */ - - -#ifndef __TOXAV -#define __TOXAV -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* vpx_image_t */ -#include - -typedef void ( *ToxAVCallback ) ( void *agent, int32_t call_idx, void *arg ); -typedef struct _ToxAv ToxAv; - -#ifndef __TOX_DEFINED__ -#define __TOX_DEFINED__ -typedef struct Tox Tox; -#endif - -#define RTP_PAYLOAD_SIZE 65535 - - -/** - * @brief Callbacks ids that handle the call states. - */ -typedef enum { - /* Requests */ - av_OnInvite, - av_OnStart, - av_OnCancel, - av_OnReject, - av_OnEnd, - - /* Responses */ - av_OnRinging, - av_OnStarting, - av_OnEnding, - - /* Protocol */ - av_OnRequestTimeout, - av_OnPeerTimeout, - av_OnMediaChange -} ToxAvCallbackID; - - -/** - * @brief Call type identifier. - */ -typedef enum { - TypeAudio = 192, - TypeVideo -} ToxAvCallType; - - -typedef enum { - av_CallNonExistant = -1, - av_CallInviting, /* when sending call invite */ - av_CallStarting, /* when getting call invite */ - av_CallActive, - av_CallHold, - av_CallHanged_up -} ToxAvCallState; - -/** - * @brief Error indicators. - */ -typedef enum { - ErrorNone = 0, - ErrorInternal = -1, /* Internal error */ - ErrorAlreadyInCall = -2, /* Already has an active call */ - ErrorNoCall = -3, /* Trying to perform call action while not in a call */ - ErrorInvalidState = -4, /* Trying to perform call action while in invalid state*/ - ErrorNoRtpSession = -5, /* Trying to perform rtp action on invalid session */ - ErrorAudioPacketLost = -6, /* Indicating packet loss */ - ErrorStartingAudioRtp = -7, /* Error in toxav_prepare_transmission() */ - ErrorStartingVideoRtp = -8 , /* Error in toxav_prepare_transmission() */ - ErrorTerminatingAudioRtp = -9, /* Returned in toxav_kill_transmission() */ - ErrorTerminatingVideoRtp = -10, /* Returned in toxav_kill_transmission() */ - ErrorPacketTooLarge = -11, /* Buffer exceeds size while encoding */ - ErrorInvalidCodecState = -12, /* Codec state not initialized */ - -} ToxAvError; - - -/** - * @brief Locally supported capabilities. - */ -typedef enum { - AudioEncoding = 1 << 0, - AudioDecoding = 1 << 1, - VideoEncoding = 1 << 2, - VideoDecoding = 1 << 3 -} ToxAvCapabilities; - - -/** - * @brief Encoding settings. - */ -typedef struct _ToxAvCodecSettings { - ToxAvCallType call_type; - - uint32_t video_bitrate; /* In kbits/s */ - uint16_t max_video_width; /* In px */ - uint16_t max_video_height; /* In px */ - - uint32_t audio_bitrate; /* In bits/s */ - uint16_t audio_frame_duration; /* In ms */ - uint32_t audio_sample_rate; /* In Hz */ - uint32_t audio_channels; -} ToxAvCSettings; - -extern const ToxAvCSettings av_DefaultSettings; -extern const uint32_t av_jbufdc; /* Jitter buffer default capacity */ -extern const uint32_t av_VADd; /* VAD default treshold */ - -/** - * @brief Start new A/V session. There can only be one session at the time. If you register more - * it will result in undefined behaviour. - * - * @param messenger The messenger handle. - * @param userdata The agent handling A/V session (i.e. phone). - * @param video_width Width of video frame. - * @param video_height Height of video frame. - * @return ToxAv* - * @retval NULL On error. - */ -ToxAv *toxav_new(Tox *messenger, int32_t max_calls); - -/** - * @brief Remove A/V session. - * - * @param av Handler. - * @return void - */ -void toxav_kill(ToxAv *av); - -/** - * @brief Register callback for call state. - * - * @param av Handler. - * @param callback The callback - * @param id One of the ToxAvCallbackID values - * @return void - */ -void toxav_register_callstate_callback (ToxAv *av, ToxAVCallback callback, ToxAvCallbackID id, void *userdata); - -/** - * @brief Register callback for recieving audio data - * - * @param av Handler. - * @param callback The callback - * @return void - */ -void toxav_register_audio_recv_callback (ToxAv *av, void (*callback)(ToxAv *, int32_t, int16_t *, int, void *), - void *user_data); - -/** - * @brief Register callback for recieving video data - * - * @param av Handler. - * @param callback The callback - * @return void - */ -void toxav_register_video_recv_callback (ToxAv *av, void (*callback)(ToxAv *, int32_t, vpx_image_t *, void *), - void *user_data); - -/** - * @brief Call user. Use its friend_id. - * - * @param av Handler. - * @param user The user. - * @param call_type Call type. - * @param ringing_seconds Ringing timeout. - * @return int - * @retval 0 Success. - * @retval ToxAvError On error. - */ -int toxav_call(ToxAv *av, int32_t *call_index, int user, const ToxAvCSettings *csettings, int ringing_seconds); - -/** - * @brief Hangup active call. - * - * @param av Handler. - * @return int - * @retval 0 Success. - * @retval ToxAvError On error. - */ -int toxav_hangup(ToxAv *av, int32_t call_index); - -/** - * @brief Answer incomming call. - * - * @param av Handler. - * @param call_type Answer with... - * @return int - * @retval 0 Success. - * @retval ToxAvError On error. - */ -int toxav_answer(ToxAv *av, int32_t call_index, const ToxAvCSettings *csettings ); - -/** - * @brief Reject incomming call. - * - * @param av Handler. - * @param reason Optional reason. Set NULL if none. - * @return int - * @retval 0 Success. - * @retval ToxAvError On error. - */ -int toxav_reject(ToxAv *av, int32_t call_index, const char *reason); - -/** - * @brief Cancel outgoing request. - * - * @param av Handler. - * @param reason Optional reason. - * @param peer_id peer friend_id - * @return int - * @retval 0 Success. - * @retval ToxAvError On error. - */ -int toxav_cancel(ToxAv *av, int32_t call_index, int peer_id, const char *reason); - -/** - * @brief Notify peer that we are changing call settings - * - * @param av Handler. - * @return int - * @retval 0 Success. - * @retval ToxAvError On error. - */ -int toxav_change_settings(ToxAv *av, int32_t call_index, const ToxAvCSettings *csettings); - -/** - * @brief Terminate transmission. Note that transmission will be terminated without informing remote peer. - * - * @param av Handler. - * @return int - * @retval 0 Success. - * @retval ToxAvError On error. - */ -int toxav_stop_call(ToxAv *av, int32_t call_index); - -/** - * @brief Must be call before any RTP transmission occurs. - * - * @param av Handler. - * @param support_video Is video supported ? 1 : 0 - * @return int - * @retval 0 Success. - * @retval ToxAvError On error. - */ -int toxav_prepare_transmission(ToxAv *av, int32_t call_index, uint32_t jbuf_size, uint32_t VAD_treshold, - int support_video); - -/** - * @brief Call this at the end of the transmission. - * - * @param av Handler. - * @return int - * @retval 0 Success. - * @retval ToxAvError On error. - */ -int toxav_kill_transmission(ToxAv *av, int32_t call_index); - -/** - * @brief Encode and send video packet. - * - * @param av Handler. - * @param frame The encoded frame. - * @param frame_size The size of the encoded frame. - * @return int - * @retval 0 Success. - * @retval ToxAvError On error. - */ -int toxav_send_video ( ToxAv *av, int32_t call_index, const uint8_t *frame, unsigned int frame_size); - -/** - * @brief Send audio frame. - * - * @param av Handler. - * @param data The audio data encoded with toxav_prepare_audio_frame(). - * @param size Its size in number of bytes. - * @return int - * @retval 0 Success. - * @retval ToxAvError On error. - */ -int toxav_send_audio ( ToxAv *av, int32_t call_index, const uint8_t *frame, unsigned int size); - -/** - * @brief Encode video frame - * - * @param av Handler - * @param dest Where to - * @param dest_max Max size - * @param input What to encode - * @return int - * @retval ToxAvError On error. - * @retval >0 On success - */ -int toxav_prepare_video_frame ( ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, vpx_image_t *input ); - -/** - * @brief Encode audio frame - * - * @param av Handler - * @param dest dest - * @param dest_max Max dest size - * @param frame The frame - * @param frame_size The frame size - * @return int - * @retval ToxAvError On error. - * @retval >0 On success - */ -int toxav_prepare_audio_frame ( ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, const int16_t *frame, - int frame_size); - -/** - * @brief Get peer transmission type. It can either be audio or video. - * - * @param av Handler. - * @param peer The peer - * @return int - * @retval ToxAvCallType On success. - * @retval ToxAvError On error. - */ -int toxav_get_peer_csettings ( ToxAv *av, int32_t call_index, int peer, ToxAvCSettings *dest ); - -/** - * @brief Get id of peer participating in conversation - * - * @param av Handler - * @param peer peer index - * @return int - * @retval ToxAvError No peer id - */ -int toxav_get_peer_id ( ToxAv *av, int32_t call_index, int peer ); - -/** - * @brief Get current call state - * - * @param av Handler - * @param call_index What call - * @return int - * @retval ToxAvCallState State id - */ -ToxAvCallState toxav_get_call_state ( ToxAv *av, int32_t call_index ); -/** - * @brief Is certain capability supported - * - * @param av Handler - * @return int - * @retval 1 Yes. - * @retval 0 No. - */ -int toxav_capability_supported ( ToxAv *av, int32_t call_index, ToxAvCapabilities capability ); - - -Tox *toxav_get_tox(ToxAv *av); - -int toxav_has_activity ( ToxAv *av, int32_t call_index, int16_t *PCM, uint16_t frame_size, float ref_energy ); - -#ifdef __cplusplus -} -#endif - -#endif /* __TOXAV */ diff --git a/protocols/Tox/src/tox/toxdns.h b/protocols/Tox/src/tox/toxdns.h deleted file mode 100644 index a0cc323b43..0000000000 --- a/protocols/Tox/src/tox/toxdns.h +++ /dev/null @@ -1,85 +0,0 @@ -/* toxdns.h - * - * Tox secure username DNS toxid resolving functions. - * - * Copyright (C) 2014 Tox project All Rights Reserved. - * - * This file is part of Tox. - * - * Tox is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Tox is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Tox. If not, see . - * - */ - -#ifndef TOXDNS_H -#define TOXDNS_H - -#include - -/* How to use this api to make secure tox dns3 requests: - * - * 1. Get the public key of a server that supports tox dns3. - * 2. use tox_dns3_new() to create a new object to create DNS requests - * and handle responses for that server. - * 3. Use tox_generate_dns3_string() to generate a string based on the name we want to query and a request_id - * that must be stored somewhere for when we want to decrypt the response. - * 4. take the string and use it for your DNS request like this: - * _4haaaaipr1o3mz0bxweox541airydbovqlbju51mb4p0ebxq.rlqdj4kkisbep2ks3fj2nvtmk4daduqiueabmexqva1jc._tox.utox.org - * 5. The TXT in the DNS you receive should look like this: - * v=tox3;id=2vgcxuycbuctvauik3plsv3d3aadv4zfjfhi3thaizwxinelrvigchv0ah3qjcsx5qhmaksb2lv2hm5cwbtx0yp - * 6. Take the id string and use it with tox_decrypt_dns3_TXT() and the request_id corresponding to the - * request we stored earlier to get the Tox id returned by the DNS server. - */ - -/* Create a new tox_dns3 object for server with server_public_key of size TOX_CLIENT_ID_SIZE. - * - * return Null on failure. - * return pointer object on success. - */ -void *tox_dns3_new(uint8_t *server_public_key); - -/* Destroy the tox dns3 object. - */ -void tox_dns3_kill(void *dns3_object); - -/* Generate a dns3 string of string_max_len used to query the dns server referred to by to - * dns3_object for a tox id registered to user with name of name_len. - * - * the uint32_t pointed by request_id will be set to the request id which must be passed to - * tox_decrypt_dns3_TXT() to correctly decode the response. - * - * This is what the string returned looks like: - * 4haaaaipr1o3mz0bxweox541airydbovqlbju51mb4p0ebxq.rlqdj4kkisbep2ks3fj2nvtmk4daduqiueabmexqva1jc - * - * returns length of string on sucess. - * returns -1 on failure. - */ -int tox_generate_dns3_string(void *dns3_object, uint8_t *string, uint16_t string_max_len, uint32_t *request_id, - uint8_t *name, uint8_t name_len); - -/* Decode and decrypt the id_record returned of length id_record_len into - * tox_id (needs to be at least TOX_FRIEND_ADDRESS_SIZE). - * - * request_id is the request id given by tox_generate_dns3_string() when creating the request. - * - * the id_record passed to this function should look somewhat like this: - * 2vgcxuycbuctvauik3plsv3d3aadv4zfjfhi3thaizwxinelrvigchv0ah3qjcsx5qhmaksb2lv2hm5cwbtx0yp - * - * returns -1 on failure. - * returns 0 on success. - * - */ -int tox_decrypt_dns3_TXT(void *dns3_object, uint8_t *tox_id, uint8_t *id_record, uint32_t id_record_len, - uint32_t request_id); - -#endif diff --git a/protocols/Tox/src/tox_account.cpp b/protocols/Tox/src/tox_account.cpp index 886bf70f7b..3648bb4dbf 100644 --- a/protocols/Tox/src/tox_account.cpp +++ b/protocols/Tox/src/tox_account.cpp @@ -1,16 +1,33 @@ #include "common.h" #include "tox_bootstrap.h" +bool CToxProto::IsOnline() +{ + return isConnected && m_iStatus > ID_STATUS_OFFLINE; +} + +int CToxProto::OnAccountLoaded(WPARAM, LPARAM) +{ + HookProtoEvent(ME_OPT_INITIALISE, &CToxProto::OnOptionsInit); + HookProtoEvent(ME_PROTO_ACCLISTCHANGED, &CToxProto::OnAccountListChanged); + HookProtoEvent(ME_DB_CONTACT_SETTINGCHANGED, &CToxProto::OnSettingsChanged); + HookProtoEvent(ME_MSG_PRECREATEEVENT, &CToxProto::OnPreCreateMessage); + + InitNetlib(); + + return 0; +} + void CToxProto::InitToxCore() { Tox_Options options = { 0 }; options.udp_disabled = getByte("DisableUDP", 0); options.ipv6enabled = !getByte("DisableIPv6", 0); - if (hNetlibUser) + if (hNetlib) { NETLIBUSERSETTINGS nlus = { sizeof(NETLIBUSERSETTINGS) }; - CallService(MS_NETLIB_GETUSERSETTINGS, (WPARAM)hNetlibUser, (LPARAM)&nlus); + CallService(MS_NETLIB_GETUSERSETTINGS, (WPARAM)hNetlib, (LPARAM)&nlus); if (nlus.useProxy) { @@ -58,11 +75,6 @@ void CToxProto::UninitToxCore() tox_kill(tox); } -bool CToxProto::IsOnline() -{ - return isConnected && m_iStatus > ID_STATUS_OFFLINE; -} - void CToxProto::DoBootstrap() { static int j = 0; @@ -77,13 +89,10 @@ void CToxProto::DoBootstrap() void CToxProto::DoTox() { - uint32_t interval = 50; - { - mir_cs(tox_lock); + mir_cslock((CRITICAL_SECTION&)toxLock); - tox_do(tox); - interval = tox_do_interval(tox); - } + tox_do(tox); + uint32_t interval = tox_do_interval(tox); Sleep(interval); } @@ -105,7 +114,7 @@ void CToxProto::PollingThread(void*) isConnected = true; debugLogA("CToxProto::PollingThread: successfuly connected to DHT"); - LoadContactList(); + LoadFriendList(); debugLogA("CToxProto::PollingThread: changing status from %i to %i", ID_STATUS_CONNECTING, m_iDesiredStatus); m_iStatus = m_iDesiredStatus; @@ -116,6 +125,14 @@ void CToxProto::PollingThread(void*) DoBootstrap(); } } + else + { + if (!tox_isconnected(tox)) + { + debugLogA("CToxProto::PollingThread: disconnected from DHT"); + SetStatus(ID_STATUS_OFFLINE); + } + } } isConnected = false; diff --git a/protocols/Tox/src/tox_accounts.cpp b/protocols/Tox/src/tox_accounts.cpp new file mode 100644 index 0000000000..147c328656 --- /dev/null +++ b/protocols/Tox/src/tox_accounts.cpp @@ -0,0 +1,43 @@ +#include "common.h" + +LIST CToxProto::accounts(1, CToxProto::CompareAccounts); + +int CToxProto::CompareAccounts(const CToxProto *p1, const CToxProto *p2) +{ + return _tcscmp(p1->m_tszUserName, p2->m_tszUserName); +} + +CToxProto* CToxProto::InitAccount(const char* protoName, const wchar_t* userName) +{ + CToxProto *ppro = new CToxProto(protoName, userName); + accounts.insert(ppro); + + return ppro; +} + +int CToxProto::UninitAccount(CToxProto* ppro) +{ + accounts.remove(ppro); + delete ppro; + + return 0; +} + +int CToxProto::OnAccountListChanged(WPARAM wParam, LPARAM lParam) +{ + PROTOACCOUNT* account = (PROTOACCOUNT*)lParam; + + if (wParam == PRAC_ADDED && !strcmp(account->szModuleName, m_szModuleName)) + { + UninitToxCore(); + DialogBoxParam( + g_hInstance, + MAKEINTRESOURCE(IDD_PROFILE_MANAGER), + account->hwndAccMgrUI, + CToxProto::ToxProfileManagerProc, + (LPARAM)this); + InitToxCore(); + } + + return 0; +} \ No newline at end of file diff --git a/protocols/Tox/src/tox_contacts.cpp b/protocols/Tox/src/tox_contacts.cpp index e9e3622da9..b696c6b70c 100644 --- a/protocols/Tox/src/tox_contacts.cpp +++ b/protocols/Tox/src/tox_contacts.cpp @@ -46,18 +46,9 @@ MCONTACT CToxProto::GetContactFromAuthEvent(HANDLE hEvent) return DbGetAuthEventContact(&dbei); } - -bool CToxProto::IsProtoContact(MCONTACT hContact) -{ - return lstrcmpiA(GetContactProto(hContact), m_szModuleName) == 0; -} - MCONTACT CToxProto::FindContact(const std::string &id) { MCONTACT hContact = NULL; - - //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)); @@ -66,7 +57,6 @@ MCONTACT CToxProto::FindContact(const std::string &id) break; } } - return hContact; } @@ -105,7 +95,7 @@ MCONTACT CToxProto::AddContact(const std::string &id, bool isTemporary) return hContact; } -void CToxProto::LoadContactList() +void CToxProto::LoadFriendList() { uint32_t count = tox_count_friendlist(tox); if (count > 0) @@ -142,58 +132,100 @@ void CToxProto::LoadContactList() } } -void CToxProto::SearchByIdAsync(void*) +int CToxProto::OnContactDeleted(MCONTACT hContact, LPARAM lParam) { - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, (HWND)1, 0); + if (hContact) + { + std::string toxId(getStringA(hContact, TOX_SETTINGS_ID)); + std::vector clientId = HexStringToData(toxId); + + uint32_t number = tox_get_friend_number(tox, clientId.data()); + if (tox_del_friend(tox, number) == 0) + { + SaveToxData(); + + return 0; + } + } + + return 1; } -void CToxProto::SearchByNameAsync(void* arg) +void CToxProto::OnFriendRequest(Tox *tox, const uint8_t *address, const uint8_t *message, const uint16_t messageSize, void *arg) { - NETLIBHTTPREQUEST request = { sizeof(NETLIBHTTPREQUEST) }; - request.requestType = REQUEST_POST; - request.szUrl = "https://toxme.se/api"; - request.flags = NLHRF_HTTP11 | NLHRF_SSL | NLHRF_NODUMP; + CToxProto *proto = (CToxProto*)arg; - request.headers = (NETLIBHTTPHEADER*)mir_alloc(sizeof(NETLIBHTTPHEADER)* 2); - request.headers[0].szName = "Content-Type"; - request.headers[0].szValue = "text/plain; charset=utf-8"; - request.headersCount = 1; + // trim tox address to tox id + std::vector clientId(address, address + TOX_CLIENT_ID_SIZE); + std::string id = proto->DataToHexString(clientId); - std::string query = "{\"action\":3,\"name\":\""; - query += (char*)arg; - query += "\"}"; + MCONTACT hContact = proto->AddContact(id, true); - request.dataLength = query.length(); - request.pData = (char*)query.c_str(); + PROTORECVEVENT pre = { 0 }; + pre.flags = PREF_UTF; + pre.timestamp = time(NULL); + pre.lParam = (DWORD)(sizeof(DWORD)* 2 + id.length() + messageSize + 5); - NETLIBHTTPREQUEST* response = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hNetlibUser, (LPARAM)&request); + /*blob is: 0(DWORD), hContact(DWORD), nick(ASCIIZ), firstName(ASCIIZ), lastName(ASCIIZ), sid(ASCIIZ), reason(ASCIIZ)*/ + PBYTE pBlob, pCurBlob; + pCurBlob = pBlob = (PBYTE)mir_calloc(pre.lParam); - if (response) - { - std::smatch match; - std::regex regex("\"public_key\": \"(.+?)\""); + *((PDWORD)pCurBlob) = 0; + pCurBlob += sizeof(DWORD); + *((PDWORD)pCurBlob) = (DWORD)hContact; + pCurBlob += sizeof(DWORD); + pCurBlob += 3; + strcpy((char *)pCurBlob, id.c_str()); + pCurBlob += id.length() + 1; + strcpy((char *)pCurBlob, (char*)message); - const std::string content = response->pData; + ProtoChainRecv(hContact, PSR_AUTH, 0, (LPARAM)&pre); +} - if (std::regex_search(content, match, regex)) - { - std::string toxId = match[1]; +void CToxProto::OnFriendNameChange(Tox *tox, const int number, const uint8_t *name, const uint16_t nameSize, void *arg) +{ + CToxProto *proto = (CToxProto*)arg; - PROTOSEARCHRESULT psr = { sizeof(PROTOSEARCHRESULT) }; - psr.flags = PSR_TCHAR; - psr.id = mir_a2t(toxId.c_str()); + MCONTACT hContact = proto->FindContact(number); + if (hContact) + { + proto->setString(hContact, "Nick", (char*)name); + } +} - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)1, (LPARAM)&psr); - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)1, 0); +void CToxProto::OnStatusMessageChanged(Tox *tox, const int number, const uint8_t* message, const uint16_t messageSize, void *arg) +{ + CToxProto *proto = (CToxProto*)arg; - CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)response); - return; - } + MCONTACT hContact = proto->FindContact(number); + if (hContact) + { + ptrW statusMessage(mir_utf8decodeW((char*)message)); + db_set_ws(hContact, "CList", "StatusMsg", statusMessage); } +} - CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)response); - mir_free(request.headers); +void CToxProto::OnUserStatusChanged(Tox *tox, int32_t number, uint8_t usertatus, void *arg) +{ + CToxProto *proto = (CToxProto*)arg; - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, (HANDLE)1, 0); - mir_free(arg); + MCONTACT hContact = proto->FindContact(number); + if (hContact) + { + TOX_USERSTATUS userstatus = (TOX_USERSTATUS)usertatus; + int status = proto->ToxToMirandaStatus(userstatus); + proto->SetContactStatus(hContact, status); + } +} + +void CToxProto::OnConnectionStatusChanged(Tox *tox, const int number, const uint8_t status, void *arg) +{ + CToxProto *proto = (CToxProto*)arg; + + MCONTACT hContact = proto->FindContact(number); + if (hContact) + { + int newStatus = status ? ID_STATUS_ONLINE : ID_STATUS_OFFLINE; + proto->SetContactStatus(hContact, newStatus); + } } \ No newline at end of file diff --git a/protocols/Tox/src/tox_events.cpp b/protocols/Tox/src/tox_events.cpp index 1a27e498ef..8a803d8144 100644 --- a/protocols/Tox/src/tox_events.cpp +++ b/protocols/Tox/src/tox_events.cpp @@ -1,17 +1,5 @@ #include "common.h" -int CToxProto::OnAccountLoaded(WPARAM, LPARAM) -{ - HookProtoEvent(ME_OPT_INITIALISE, &CToxProto::OnOptionsInit); - HookProtoEvent(ME_PROTO_ACCLISTCHANGED, &CToxProto::OnAccountListChanged); - HookProtoEvent(ME_DB_CONTACT_SETTINGCHANGED, &CToxProto::OnSettingsChanged); - HookProtoEvent(ME_MSG_PRECREATEEVENT, &CToxProto::OnPreCreateMessage); - - InitNetlib(); - - return 0; -} - int CToxProto::OnPreShutdown(WPARAM, LPARAM) { UninitNetlib(); @@ -29,25 +17,6 @@ INT_PTR CToxProto::OnAccountManagerInit(WPARAM, LPARAM lParam) (LPARAM)this); } -int CToxProto::OnAccountListChanged(WPARAM wParam, LPARAM lParam) -{ - PROTOACCOUNT* account = (PROTOACCOUNT*)lParam; - - if (wParam == PRAC_ADDED && !strcmp(account->szModuleName, m_szModuleName)) - { - UninitToxCore(); - DialogBoxParam( - g_hInstance, - MAKEINTRESOURCE(IDD_PROFILE_MANAGER), - account->hwndAccMgrUI, - CToxProto::ToxProfileManagerProc, - (LPARAM)this); - InitToxCore(); - } - - return 0; -} - int CToxProto::OnOptionsInit(WPARAM wParam, LPARAM) { char *title = mir_t2a(m_tszUserName); @@ -69,25 +38,6 @@ int CToxProto::OnOptionsInit(WPARAM wParam, LPARAM) return 0; } -int CToxProto::OnContactDeleted(MCONTACT hContact, LPARAM lParam) -{ - if (hContact) - { - std::string toxId(getStringA(hContact, TOX_SETTINGS_ID)); - std::vector clientId = HexStringToData(toxId); - - uint32_t number = tox_get_friend_number(tox, clientId.data()); - if (tox_del_friend(tox, number) == 0) - { - SaveToxData(); - - return 0; - } - } - - return 1; -} - int CToxProto::OnSettingsChanged(WPARAM hContact, LPARAM lParam) { DBCONTACTWRITESETTING* dbcws = (DBCONTACTWRITESETTING*)lParam; @@ -111,228 +61,4 @@ int CToxProto::OnSettingsChanged(WPARAM hContact, LPARAM lParam) } return 0; -} - -int CToxProto::OnPreCreateMessage(WPARAM wParam, LPARAM lParam) -{ - MessageWindowEvent *evt = (MessageWindowEvent *)lParam; - if (strcmp(GetContactProto(evt->hContact), m_szModuleName)) - { - return 0; - } - - char *message = (char*)evt->dbei->pBlob; - if (strncmp(message, "/me ", 4) == 0) - { - BYTE *action = (BYTE*)mir_alloc(sizeof(BYTE)* (evt->dbei->cbBlob - 4)); - memcpy(action, (char*)&evt->dbei->pBlob[4], evt->dbei->cbBlob - 4); - mir_free(evt->dbei->pBlob); - evt->dbei->pBlob = action; - evt->dbei->cbBlob -= 4; - - evt->dbei->eventType = TOX_DB_EVENT_TYPE_ACTION; - } - - return 1; -} - -void CToxProto::OnFriendRequest(Tox *tox, const uint8_t *address, const uint8_t *message, const uint16_t messageSize, void *arg) -{ - CToxProto *proto = (CToxProto*)arg; - - // trim tox address to tox id - std::vector clientId(address, address + TOX_CLIENT_ID_SIZE); - std::string id = proto->DataToHexString(clientId); - - proto->RaiseAuthRequestEvent(time(NULL), id.c_str(), (char*)message); - - proto->SaveToxData(); -} - -void CToxProto::OnFriendMessage(Tox *tox, const int number, const uint8_t *message, const uint16_t messageSize, void *arg) -{ - CToxProto *proto = (CToxProto*)arg; - - MCONTACT hContact = proto->FindContact(number); - if (hContact) - { - PROTORECVEVENT recv = { 0 }; - recv.flags = PREF_UTF; - recv.timestamp = time(NULL); - recv.szMessage = (char*)message; - - ProtoChainRecvMsg(hContact, &recv); - } -} - -void CToxProto::OnFriendAction(Tox *tox, const int number, const uint8_t *action, const uint16_t actionSize, void *arg) -{ - CToxProto *proto = (CToxProto*)arg; - - MCONTACT hContact = proto->FindContact(number); - if (hContact) - { - proto->AddDbEvent( - hContact, - TOX_DB_EVENT_TYPE_ACTION, - time(NULL), - DBEF_UTF, - actionSize, - (BYTE*)action); - } -} - -void CToxProto::OnTypingChanged(Tox *tox, const int number, uint8_t isTyping, void *arg) -{ - CToxProto *proto = (CToxProto*)arg; - - MCONTACT hContact = proto->FindContact(number); - if (hContact) - { - CallService(MS_PROTO_CONTACTISTYPING, hContact, (LPARAM)isTyping); - } -} - -void CToxProto::OnFriendNameChange(Tox *tox, const int number, const uint8_t *name, const uint16_t nameSize, void *arg) -{ - CToxProto *proto = (CToxProto*)arg; - - MCONTACT hContact = proto->FindContact(number); - if (hContact) - { - proto->setString(hContact, "Nick", (char*)name); - } -} - -void CToxProto::OnStatusMessageChanged(Tox *tox, const int number, const uint8_t* message, const uint16_t messageSize, void *arg) -{ - CToxProto *proto = (CToxProto*)arg; - - MCONTACT hContact = proto->FindContact(number); - if (hContact) - { - ptrW statusMessage(mir_utf8decodeW((char*)message)); - db_set_ws(hContact, "CList", "StatusMsg", statusMessage); - } -} - -void CToxProto::OnUserStatusChanged(Tox *tox, int32_t number, uint8_t usertatus, void *arg) -{ - CToxProto *proto = (CToxProto*)arg; - - MCONTACT hContact = proto->FindContact(number); - if (hContact) - { - TOX_USERSTATUS userstatus = (TOX_USERSTATUS)usertatus; - int status = proto->ToxToMirandaStatus(userstatus); - proto->SetContactStatus(hContact, status); - } -} - -void CToxProto::OnConnectionStatusChanged(Tox *tox, const int number, const uint8_t status, void *arg) -{ - CToxProto *proto = (CToxProto*)arg; - - MCONTACT hContact = proto->FindContact(number); - if (hContact) - { - int newStatus = status ? ID_STATUS_ONLINE : ID_STATUS_OFFLINE; - proto->SetContactStatus(hContact, newStatus); - } -} - -void CToxProto::OnReadReceipt(Tox *tox, int32_t number, uint32_t receipt, void *arg) -{ - CToxProto *proto = (CToxProto*)arg; - - MCONTACT hContact = proto->FindContact(number); - if (hContact) - { - proto->ProtoBroadcastAck( - hContact, - ACKTYPE_MESSAGE, - ACKRESULT_SUCCESS, - (HANDLE)receipt, 0); - } -} - -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; - - MCONTACT hContact = proto->FindContact(number); - if (hContact) - { - 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; - - PROTORECVFILET pre = { 0 }; - pre.flags = PREF_TCHAR; - pre.fileCount = 1; - pre.timestamp = time(NULL); - pre.tszDescription = _T(""); - pre.ptszFiles = (TCHAR**)mir_alloc(sizeof(TCHAR*)* 2); - pre.ptszFiles[0] = mir_utf8decodeT((char*)fileName); - pre.ptszFiles[1] = NULL; - pre.lParam = (LPARAM)fileNumber; - ProtoChainRecvFile(hContact, &pre); - } -} - -void CToxProto::OnFileData(Tox *tox, int32_t number, uint8_t fileNumber, const uint8_t *data, uint16_t size, void *arg) -{ - CToxProto *proto = (CToxProto*)arg; - - MCONTACT hContact = proto->FindContact(number); - if (hContact) - { - FileTransferParam *transfer = proto->transfers.at(fileNumber); - - TCHAR filePath[MAX_PATH]; - mir_sntprintf(filePath, SIZEOF(filePath), _T("%s%s"), transfer->pfts.tszWorkingDir, transfer->pfts.tszCurrentFile); - - FILE *hFile = NULL; - if (transfer->pfts.currentFileProgress == 0) - { - hFile = _tfopen(filePath, _T("wb")); - proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)fileNumber, 0); - } - else - { - hFile = _tfopen(filePath, _T("ab")); - } - if (hFile != NULL) - { - 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); - } - 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) -{ - CToxProto *proto = (CToxProto*)arg; - - MCONTACT hContact = proto->FindContact(number); - if (hContact) - { - FileTransferParam *transfer = proto->transfers.at(fileNumber); - - switch (type) - { - case TOX_FILECONTROL_ACCEPT: - break; - - 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); - break; - } - } } \ No newline at end of file diff --git a/protocols/Tox/src/tox_instances.cpp b/protocols/Tox/src/tox_instances.cpp deleted file mode 100644 index 414cd7b767..0000000000 --- a/protocols/Tox/src/tox_instances.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "common.h" - -LIST CToxProto::instanceList(1, CToxProto::CompareProtos); - -int CToxProto::CompareProtos(const CToxProto *p1, const CToxProto *p2) -{ - return wcscmp(p1->m_tszUserName, p2->m_tszUserName); -} - -CToxProto* CToxProto::InitProtoInstance(const char* protoName, const wchar_t* userName) -{ - CToxProto *ppro = new CToxProto(protoName, userName); - instanceList.insert(ppro); - - return ppro; -} - -int CToxProto::UninitProtoInstance(CToxProto* ppro) -{ - instanceList.remove(ppro); - - delete ppro; - - return 0; -} - -void CToxProto::UninitInstances() -{ - instanceList.destroy(); -} - -CToxProto* CToxProto::GetContactInstance(MCONTACT hContact) -{ - char *proto = (char *)CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0); - - if (proto == NULL) - return NULL; - - for (int i = 0; i < instanceList.getCount(); i++) - if ( !::strcmp(proto, instanceList[i]->m_szModuleName)) - return instanceList[i]; - - return NULL; -} \ No newline at end of file diff --git a/protocols/Tox/src/tox_messages.cpp b/protocols/Tox/src/tox_messages.cpp new file mode 100644 index 0000000000..0c57fbf68d --- /dev/null +++ b/protocols/Tox/src/tox_messages.cpp @@ -0,0 +1,83 @@ +#include "common.h" + +void CToxProto::OnFriendMessage(Tox *tox, const int number, const uint8_t *message, const uint16_t messageSize, void *arg) +{ + CToxProto *proto = (CToxProto*)arg; + + MCONTACT hContact = proto->FindContact(number); + if (hContact) + { + PROTORECVEVENT recv = { 0 }; + recv.flags = PREF_UTF; + recv.timestamp = time(NULL); + recv.szMessage = (char*)message; + + ProtoChainRecvMsg(hContact, &recv); + } +} + +void CToxProto::OnFriendAction(Tox *tox, const int number, const uint8_t *action, const uint16_t actionSize, void *arg) +{ + CToxProto *proto = (CToxProto*)arg; + + MCONTACT hContact = proto->FindContact(number); + if (hContact) + { + proto->AddDbEvent( + hContact, + TOX_DB_EVENT_TYPE_ACTION, + time(NULL), + DBEF_UTF, + actionSize, + (BYTE*)action); + } +} + +void CToxProto::OnTypingChanged(Tox *tox, const int number, uint8_t isTyping, void *arg) +{ + CToxProto *proto = (CToxProto*)arg; + + MCONTACT hContact = proto->FindContact(number); + if (hContact) + { + CallService(MS_PROTO_CONTACTISTYPING, hContact, (LPARAM)isTyping); + } +} + +void CToxProto::OnReadReceipt(Tox *tox, int32_t number, uint32_t receipt, void *arg) +{ + CToxProto *proto = (CToxProto*)arg; + + MCONTACT hContact = proto->FindContact(number); + if (hContact) + { + proto->ProtoBroadcastAck( + hContact, + ACKTYPE_MESSAGE, + ACKRESULT_SUCCESS, + (HANDLE)receipt, 0); + } +} + +int CToxProto::OnPreCreateMessage(WPARAM wParam, LPARAM lParam) +{ + MessageWindowEvent *evt = (MessageWindowEvent *)lParam; + if (strcmp(GetContactProto(evt->hContact), m_szModuleName)) + { + return 0; + } + + char *message = (char*)evt->dbei->pBlob; + if (strncmp(message, "/me ", 4) == 0) + { + BYTE *action = (BYTE*)mir_alloc(sizeof(BYTE)* (evt->dbei->cbBlob - 4)); + memcpy(action, (char*)&evt->dbei->pBlob[4], evt->dbei->cbBlob - 4); + mir_free(evt->dbei->pBlob); + evt->dbei->pBlob = action; + evt->dbei->cbBlob -= 4; + + evt->dbei->eventType = TOX_DB_EVENT_TYPE_ACTION; + } + + return 1; +} \ No newline at end of file diff --git a/protocols/Tox/src/tox_netlib.cpp b/protocols/Tox/src/tox_netlib.cpp index a2fea7a615..7ebddc66b2 100644 --- a/protocols/Tox/src/tox_netlib.cpp +++ b/protocols/Tox/src/tox_netlib.cpp @@ -10,13 +10,13 @@ void CToxProto::InitNetlib() nlu.flags = NUF_OUTGOING | NUF_INCOMING | NUF_HTTPCONNS | NUF_UNICODE; nlu.ptszDescriptiveName = name; nlu.szSettingsModule = m_szModuleName; - hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); + hNetlib = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nlu); debugLogA("Setting protocol/module name to '%s'", m_szModuleName); } void CToxProto::UninitNetlib() { - Netlib_CloseHandle(hNetlibUser); - hNetlibUser = NULL; + Netlib_CloseHandle(hNetlib); + hNetlib = NULL; } diff --git a/protocols/Tox/src/tox_options.cpp b/protocols/Tox/src/tox_options.cpp index 2c920f95b2..7df550d585 100644 --- a/protocols/Tox/src/tox_options.cpp +++ b/protocols/Tox/src/tox_options.cpp @@ -1,27 +1,5 @@ #include "common.h" -INT_PTR CToxProto::SearchDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - CToxProto *proto = (CToxProto*)GetWindowLongPtr(hwnd, GWLP_USERDATA); - - switch (uMsg) - { - case WM_INITDIALOG: - TranslateDialogDefault(hwnd); - { - proto = (CToxProto*)lParam; - SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam); - - //ShowWindow(GetDlgItem(GetParent(hwnd), 1408/*IDC_BYCUSTOM*/), SW_HIDE); - //ShowWindow(GetDlgItem(GetParent(hwnd), 1402/*IDC_ADVANCEDGROUP*/), SW_HIDE); - SetDlgItemText(GetParent(hwnd), 1408/*IDC_BYCUSTOM*/, TranslateT("Query")); - } - return TRUE; - } - - return FALSE; -} - INT_PTR CToxProto::MainOptionsProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { CToxProto *proto = (CToxProto*)GetWindowLongPtr(hwnd, GWLP_USERDATA); @@ -121,83 +99,5 @@ INT_PTR CToxProto::MainOptionsProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l break; } - return FALSE; -} - -INT_PTR CToxProto::ToxProfileManagerProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - CToxProto *proto = (CToxProto*)GetWindowLongPtr(hwnd, GWLP_USERDATA); - TCHAR *profilePath = (TCHAR*)GetWindowLongPtr(hwnd, DWLP_USER); - - switch (uMsg) - { - case WM_INITDIALOG: - TranslateDialogDefault(hwnd); - { - proto = (CToxProto*)lParam; - SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam); - - profilePath = (TCHAR*)mir_calloc(sizeof(TCHAR)* MAX_PATH); - SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)profilePath); - - CheckDlgButton(hwnd, IDC_CREATE_NEW, TRUE); - } - return TRUE; - - case WM_CLOSE: - EndDialog(hwnd, 0); - break; - - case WM_DESTROY: - mir_free(profilePath); - break; - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case IDC_USE_EXISTING: - EnableWindow(GetDlgItem(hwnd, IDC_PROFILE_PATH), IsDlgButtonChecked(hwnd, IDC_USE_EXISTING)); - EnableWindow(GetDlgItem(hwnd, IDC_BROWSE_PROFILE), IsDlgButtonChecked(hwnd, IDC_USE_EXISTING)); - break; - - case IDC_BROWSE_PROFILE: - { - TCHAR filter[MAX_PATH] = { 0 }; - mir_sntprintf(filter, MAX_PATH, _T("%s\0*.*"), TranslateT("All files (*.*)")); - - OPENFILENAME ofn = { sizeof(ofn) }; - ofn.hwndOwner = hwnd; - ofn.lpstrFilter = filter; - ofn.nFilterIndex = 1; - ofn.lpstrFile = profilePath; - ofn.lpstrTitle = TranslateT("Select tox profile"); - ofn.nMaxFile = MAX_PATH; - ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_EXPLORER; - - if (GetOpenFileName(&ofn) && profilePath) - { - SetDlgItemText(hwnd, IDC_PROFILE_PATH, profilePath); - } - } - break; - - case IDOK: - { - if (IsDlgButtonChecked(hwnd, IDC_USE_EXISTING)) - { - if (profilePath != NULL) - { - std::tstring toxProfilePath = proto->GetToxProfilePath(); - CopyFile(profilePath, toxProfilePath.c_str(), FALSE); - } - } - EndDialog(hwnd, 1); - } - break; - - } - break; - } - return FALSE; } \ No newline at end of file diff --git a/protocols/Tox/src/tox_profile.cpp b/protocols/Tox/src/tox_profile.cpp new file mode 100644 index 0000000000..145b839f0c --- /dev/null +++ b/protocols/Tox/src/tox_profile.cpp @@ -0,0 +1,79 @@ +#include "common.h" + +INT_PTR CToxProto::ToxProfileManagerProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + CToxProto *proto = (CToxProto*)GetWindowLongPtr(hwnd, GWLP_USERDATA); + TCHAR *profilePath = (TCHAR*)GetWindowLongPtr(hwnd, DWLP_USER); + + switch (uMsg) + { + case WM_INITDIALOG: + TranslateDialogDefault(hwnd); + { + proto = (CToxProto*)lParam; + SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam); + + profilePath = (TCHAR*)mir_calloc(sizeof(TCHAR)* MAX_PATH); + SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR)profilePath); + + CheckDlgButton(hwnd, IDC_CREATE_NEW, TRUE); + } + return TRUE; + + case WM_CLOSE: + EndDialog(hwnd, 0); + break; + + case WM_DESTROY: + mir_free(profilePath); + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_USE_EXISTING: + EnableWindow(GetDlgItem(hwnd, IDC_PROFILE_PATH), IsDlgButtonChecked(hwnd, IDC_USE_EXISTING)); + EnableWindow(GetDlgItem(hwnd, IDC_BROWSE_PROFILE), IsDlgButtonChecked(hwnd, IDC_USE_EXISTING)); + break; + + case IDC_BROWSE_PROFILE: + { + TCHAR filter[MAX_PATH] = { 0 }; + mir_sntprintf(filter, MAX_PATH, _T("%s\0*.*"), TranslateT("All files (*.*)")); + + OPENFILENAME ofn = { sizeof(ofn) }; + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = filter; + ofn.nFilterIndex = 1; + ofn.lpstrFile = profilePath; + ofn.lpstrTitle = TranslateT("Select tox profile"); + ofn.nMaxFile = MAX_PATH; + ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_EXPLORER; + + if (GetOpenFileName(&ofn) && profilePath) + { + SetDlgItemText(hwnd, IDC_PROFILE_PATH, profilePath); + } + } + break; + + case IDOK: + { + if (IsDlgButtonChecked(hwnd, IDC_USE_EXISTING)) + { + if (profilePath != NULL) + { + std::tstring toxProfilePath = proto->GetToxProfilePath(); + CopyFile(profilePath, toxProfilePath.c_str(), FALSE); + } + } + EndDialog(hwnd, 1); + } + break; + + } + break; + } + + return FALSE; +} \ No newline at end of file diff --git a/protocols/Tox/src/tox_proto.cpp b/protocols/Tox/src/tox_proto.cpp index 5734700a99..7d9a5150a4 100644 --- a/protocols/Tox/src/tox_proto.cpp +++ b/protocols/Tox/src/tox_proto.cpp @@ -1,9 +1,7 @@ #include "common.h" CToxProto::CToxProto(const char* protoName, const TCHAR* userName) : - PROTO(protoName, userName), - fileTransfers(1, NumericKeySortT), - hFileProcess(0) +PROTO(protoName, userName) { InitToxCore(); @@ -51,7 +49,7 @@ DWORD_PTR __cdecl CToxProto::GetCaps(int type, MCONTACT hContact) switch (type) { case PFLAGNUM_1: - return PF1_IM | PF1_FILERECV | PF1_AUTHREQ | PF1_EXTSEARCH; + return PF1_IM | PF1_FILE | PF1_AUTHREQ | PF1_EXTSEARCH; case PFLAGNUM_2: return PF2_ONLINE | PF2_SHORTAWAY | PF2_LIGHTDND; case PFLAGNUM_4: @@ -108,7 +106,12 @@ int __cdecl CToxProto::Authorize(HANDLE hDbEvent) } int __cdecl CToxProto::AuthDeny(HANDLE hDbEvent, const PROTOCHAR* szReason) { return 0; } -int __cdecl CToxProto::AuthRecv(MCONTACT hContact, PROTORECVEVENT*) { return 0; } + +int __cdecl CToxProto::AuthRecv(MCONTACT, PROTORECVEVENT* pre) +{ + return Proto_AuthRecv(m_szModuleName, pre); + // return 0; +} int __cdecl CToxProto::AuthRequest(MCONTACT hContact, const PROTOCHAR* szMessage) { @@ -117,8 +120,8 @@ int __cdecl CToxProto::AuthRequest(MCONTACT hContact, const PROTOCHAR* szMessage ptrA reason(mir_utf8encodeW(szMessage)); - int32_t friendnumber = tox_add_friend(tox, &clientId[0], (uint8_t*)(char*)reason, (uint16_t)strlen(reason)); - if (friendnumber >= 0) + int32_t number = tox_add_friend(tox, &clientId[0], (uint8_t*)(char*)reason, (uint16_t)strlen(reason)); + if (number >= 0) { SaveToxData(); @@ -130,7 +133,7 @@ int __cdecl CToxProto::AuthRequest(MCONTACT hContact, const PROTOCHAR* szMessage delSetting(hContact, "Auth"); std::vector username(TOX_MAX_NAME_LENGTH); - tox_get_name(tox, friendnumber, &username[0]); + tox_get_name(tox, number, &username[0]); std::string nick(username.begin(), username.end()); setString(hContact, "Nick", nick.c_str()); @@ -150,9 +153,13 @@ HANDLE __cdecl CToxProto::FileAllow(MCONTACT hContact, HANDLE hTransfer, const P uint32_t number = tox_get_friend_number(tox, clientId.data()); uint8_t fileNumber = (uint8_t)hTransfer; - transfers.at(fileNumber)->pfts.tszWorkingDir = mir_tstrdup(tszPath); + FileTransferParam *transfer = transfers.at(fileNumber); + transfer->pfts.tszWorkingDir = mir_tstrdup(tszPath); - tox_file_send_control(tox, number, 1, fileNumber, TOX_FILECONTROL_ACCEPT, NULL, 0); + //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; } @@ -177,7 +184,31 @@ int __cdecl CToxProto::FileDeny(MCONTACT hContact, HANDLE hTransfer, const PROTO return FileCancel(hContact, hTransfer); } -int __cdecl CToxProto::FileResume(HANDLE hTransfer, int* action, const PROTOCHAR** szFilename) { return 0; } +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; } @@ -265,12 +296,41 @@ int __cdecl CToxProto::SendContacts(MCONTACT hContact, int flags, int nContacts, HANDLE __cdecl CToxProto::SendFile(MCONTACT hContact, const PROTOCHAR* szDescription, PROTOCHAR** ppszFiles) { - CFileTransfer *transfer = new CFileSendTransfer(hContact, InterlockedIncrement(&hFileProcess)); - transfer->ProcessTransferedFiles(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"); + } - ForkThread(&CToxProto::SendFilesAsync, transfer); + 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)transfer->GetTransferNumber(); + return (HANDLE)fileNumber; } int __cdecl CToxProto::SendMsg(MCONTACT hContact, int flags, const char* msg) diff --git a/protocols/Tox/src/tox_proto.h b/protocols/Tox/src/tox_proto.h index 81d03f952c..4718ac7c3f 100644 --- a/protocols/Tox/src/tox_proto.h +++ b/protocols/Tox/src/tox_proto.h @@ -1,16 +1,16 @@ #ifndef _TOX_PROTO_H_ #define _TOX_PROTO_H_ -class CFileTransfer; - struct FileTransferParam { PROTOFILETRANSFERSTATUS pfts; - uint8_t number; + int number; - FileTransferParam(uint8_t number, const TCHAR* fileName, size_t fileSize) + FileTransferParam(int fileNumber, const TCHAR* fileName, size_t fileSize) { - pfts = { sizeof(PROTOFILETRANSFERSTATUS) }; + number = fileNumber; + + pfts.cbSize = sizeof(PROTOFILETRANSFERSTATUS); pfts.flags = PFTS_TCHAR; pfts.totalFiles = 1; pfts.ptszFiles = (TCHAR**)mir_alloc(sizeof(TCHAR*)*(pfts.totalFiles + 1)); @@ -93,30 +93,34 @@ public: virtual int __cdecl OnEvent(PROTOEVENTTYPE iEventType, WPARAM wParam, LPARAM lParam); // instances - static CToxProto* InitProtoInstance(const char* protoName, const wchar_t* userName); - static int UninitProtoInstance(CToxProto* ppro); - - static CToxProto* GetContactInstance(MCONTACT hContact); - static void UninitInstances(); + static CToxProto* InitAccount(const char* protoName, const wchar_t* userName); + static int UninitAccount(CToxProto* ppro); private: Tox *tox; - mir_cs tox_lock; - HANDLE hPollingThread; - bool isTerminated; - bool isConnected; - HANDLE hNetlibUser; - ULONG hFileProcess; - LIST fileTransfers; + mir_cs toxLock; + HANDLE hNetlib, hPollingThread; + bool isTerminated, isConnected; std::map transfers; // tox void InitToxCore(); void UninitToxCore(); - // instances - static LIST instanceList; - static int CompareProtos(const CToxProto *p1, const CToxProto *p2); + // ??? + void DoBootstrap(); + void DoTox(); + + void __cdecl PollingThread(void*); + + // tox profile + static INT_PTR CALLBACK ToxProfileManagerProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + + // accounts + static LIST accounts; + static int CompareAccounts(const CToxProto *p1, const CToxProto *p2); + + int __cdecl OnAccountListChanged(WPARAM wParam, LPARAM lParam); // netlib void InitNetlib(); @@ -124,61 +128,62 @@ private: // account bool IsOnline(); + int __cdecl OnAccountLoaded(WPARAM, LPARAM); - void DoBootstrap(); - void DoTox(); - void __cdecl PollingThread(void*); - - //events - int __cdecl OnAccountLoaded(WPARAM, LPARAM); - int __cdecl OnContactDeleted(MCONTACT, LPARAM); + // events int __cdecl OnPreShutdown(WPARAM, LPARAM); + int __cdecl OnSettingsChanged(WPARAM wParam, LPARAM lParam); + // options + static INT_PTR CALLBACK MainOptionsProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); int __cdecl OnOptionsInit(WPARAM wParam, LPARAM lParam); - int __cdecl OnSettingsChanged(WPARAM wParam, LPARAM lParam); - int __cdecl OnAccountListChanged(WPARAM wParam, LPARAM lParam); - int __cdecl OnPreCreateMessage(WPARAM wParam, LPARAM lParam); INT_PTR __cdecl OnAccountManagerInit(WPARAM, LPARAM); - static void OnFriendRequest(Tox *tox, const uint8_t *address, const uint8_t *message, const uint16_t messageSize, void *arg); - static void OnFriendMessage(Tox *tox, const int number, const uint8_t *message, const uint16_t messageSize, void *arg); - static void OnFriendAction(Tox *tox, const int number, const uint8_t *action, const uint16_t actionSize, void *arg); - static void OnTypingChanged(Tox *tox, const int number, uint8_t isTyping, void *arg); - static void OnFriendNameChange(Tox *tox, const int number, const uint8_t *name, const uint16_t nameSize, void *arg); - static void OnStatusMessageChanged(Tox *tox, const int number, const uint8_t* message, const uint16_t messageSize, void *arg); - static void OnUserStatusChanged(Tox *tox, int32_t number, uint8_t usertatus, void *arg); - 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); - 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); - // contacts WORD GetContactStatus(MCONTACT hContact); bool IsContactOnline(MCONTACT hContact); void SetContactStatus(MCONTACT hContact, WORD status); void SetAllContactsStatus(WORD status); - bool IsProtoContact(MCONTACT hContact); + MCONTACT FindContact(const std::string &id); MCONTACT FindContact(const int friendNumber); MCONTACT AddContact(const std::string &id, bool isTemporary = false); MCONTACT GetContactFromAuthEvent(HANDLE hEvent); - void LoadContactList(); + void LoadFriendList(); + int __cdecl OnContactDeleted(MCONTACT, LPARAM); + + static void OnFriendRequest(Tox *tox, const uint8_t *address, const uint8_t *message, const uint16_t messageSize, void *arg); + static void OnFriendNameChange(Tox *tox, const int number, const uint8_t *name, const uint16_t nameSize, void *arg); + static void OnStatusMessageChanged(Tox *tox, const int number, const uint8_t* message, const uint16_t messageSize, void *arg); + static void OnUserStatusChanged(Tox *tox, int32_t number, uint8_t usertatus, void *arg); + static void OnConnectionStatusChanged(Tox *tox, const int number, const uint8_t status, void *arg); + + // contacts search void __cdecl SearchByIdAsync(void* arg); void __cdecl SearchByNameAsync(void* arg); - // file transfer + static INT_PTR CALLBACK SearchDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + + // messages + static void OnFriendMessage(Tox *tox, const int number, const uint8_t *message, const uint16_t messageSize, void *arg); + static void OnFriendAction(Tox *tox, const int number, const uint8_t *action, const uint16_t actionSize, void *arg); + static void OnTypingChanged(Tox *tox, const int number, uint8_t isTyping, void *arg); + static void OnReadReceipt(Tox *tox, int32_t number, uint32_t receipt, void *arg); + + int __cdecl OnPreCreateMessage(WPARAM wParam, LPARAM lParam); + + // transfer void __cdecl SendFileAsync(void* arg); - void __cdecl SendFilesAsync(void* arg); - CFileTransfer *GetFileTransferByFileNumber(int fileNumber); + //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 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); // utils TOX_USERSTATUS MirandaToToxStatus(int status); @@ -188,7 +193,6 @@ private: static void ShowNotification(const wchar_t *caption, const wchar_t *message, int flags = 0, MCONTACT hContact = NULL); HANDLE AddDbEvent(MCONTACT hContact, WORD type, DWORD timestamp, DWORD flags, DWORD cbBlob, PBYTE pBlob); - void RaiseAuthRequestEvent(DWORD timestamp, const char* toxId, const char* reason); std::vector HexStringToData(std::string hex); std::string DataToHexString(std::vector); @@ -201,11 +205,6 @@ private: void LoadToxData(); void SaveToxData(); - - // dialogs - static INT_PTR CALLBACK SearchDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); - static INT_PTR CALLBACK MainOptionsProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); - static INT_PTR CALLBACK ToxProfileManagerProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); }; #endif //_TOX_PROTO_H_ \ No newline at end of file diff --git a/protocols/Tox/src/tox_search.cpp b/protocols/Tox/src/tox_search.cpp new file mode 100644 index 0000000000..82dcbd5be7 --- /dev/null +++ b/protocols/Tox/src/tox_search.cpp @@ -0,0 +1,79 @@ +#include "common.h" + +void CToxProto::SearchByIdAsync(void*) +{ + ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, (HWND)1, 0); +} + +void CToxProto::SearchByNameAsync(void* arg) +{ + NETLIBHTTPREQUEST request = { sizeof(NETLIBHTTPREQUEST) }; + request.requestType = REQUEST_POST; + request.szUrl = "https://toxme.se/api"; + request.flags = NLHRF_HTTP11 | NLHRF_SSL | NLHRF_NODUMP; + + request.headers = (NETLIBHTTPHEADER*)mir_alloc(sizeof(NETLIBHTTPHEADER)* 2); + request.headers[0].szName = "Content-Type"; + request.headers[0].szValue = "text/plain; charset=utf-8"; + request.headersCount = 1; + + std::string query = "{\"action\":3,\"name\":\""; + query += (char*)arg; + query += "\"}"; + + request.dataLength = query.length(); + request.pData = (char*)query.c_str(); + + NETLIBHTTPREQUEST* response = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hNetlib, (LPARAM)&request); + + if (response) + { + std::smatch match; + std::regex regex("\"public_key\": \"(.+?)\""); + + const std::string content = response->pData; + + if (std::regex_search(content, match, regex)) + { + std::string toxId = match[1]; + + PROTOSEARCHRESULT psr = { sizeof(PROTOSEARCHRESULT) }; + psr.flags = PSR_TCHAR; + psr.id = mir_a2t(toxId.c_str()); + + ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, (HANDLE)1, (LPARAM)&psr); + ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, (HANDLE)1, 0); + + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)response); + return; + } + } + + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)response); + mir_free(request.headers); + + ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_FAILED, (HANDLE)1, 0); + mir_free(arg); +} + +INT_PTR CToxProto::SearchDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + CToxProto *proto = (CToxProto*)GetWindowLongPtr(hwnd, GWLP_USERDATA); + + switch (uMsg) + { + case WM_INITDIALOG: + TranslateDialogDefault(hwnd); + { + proto = (CToxProto*)lParam; + SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam); + + //ShowWindow(GetDlgItem(GetParent(hwnd), 1408/*IDC_BYCUSTOM*/), SW_HIDE); + //ShowWindow(GetDlgItem(GetParent(hwnd), 1402/*IDC_ADVANCEDGROUP*/), SW_HIDE); + SetDlgItemText(GetParent(hwnd), 1408/*IDC_BYCUSTOM*/, TranslateT("Query")); + } + return TRUE; + } + + return FALSE; +} \ No newline at end of file diff --git a/protocols/Tox/src/tox_services.cpp b/protocols/Tox/src/tox_services.cpp deleted file mode 100644 index e74c41ff98..0000000000 --- a/protocols/Tox/src/tox_services.cpp +++ /dev/null @@ -1,2 +0,0 @@ -#include "common.h" - diff --git a/protocols/Tox/src/tox_transfer.cpp b/protocols/Tox/src/tox_transfer.cpp new file mode 100644 index 0000000000..d91d18ca7c --- /dev/null +++ b/protocols/Tox/src/tox_transfer.cpp @@ -0,0 +1,128 @@ +#include "common.h" + +void CToxProto::SendFileAsync(void* arg) +{ + 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) + { + return; + } + + 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 + { + ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer->number, 0); + } +} + +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; + + MCONTACT hContact = proto->FindContact(number); + if (hContact) + { + 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; + + PROTORECVFILET pre = { 0 }; + pre.flags = PREF_TCHAR; + pre.fileCount = 1; + pre.timestamp = time(NULL); + pre.tszDescription = _T(""); + pre.ptszFiles = (TCHAR**)mir_alloc(sizeof(TCHAR*)* 2); + pre.ptszFiles[0] = mir_utf8decodeT((char*)fileName); + pre.ptszFiles[1] = NULL; + pre.lParam = (LPARAM)fileNumber; + ProtoChainRecvFile(hContact, &pre); + } +} + +void CToxProto::OnFileData(Tox *tox, int32_t number, uint8_t fileNumber, const uint8_t *data, uint16_t size, void *arg) +{ + CToxProto *proto = (CToxProto*)arg; + + MCONTACT hContact = proto->FindContact(number); + if (hContact) + { + FileTransferParam *transfer = proto->transfers.at(fileNumber); + + TCHAR filePath[MAX_PATH]; + mir_sntprintf(filePath, SIZEOF(filePath), _T("%s%s"), transfer->pfts.tszWorkingDir, transfer->pfts.tszCurrentFile); + + FILE *hFile = NULL; + if (transfer->pfts.currentFileProgress == 0) + { + hFile = _tfopen(filePath, _T("wb+")); + proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)fileNumber, 0); + } + else + { + hFile = _tfopen(filePath, _T("ab")); + } + 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); + } + 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) +{ + CToxProto *proto = (CToxProto*)arg; + + MCONTACT hContact = proto->FindContact(number); + if (hContact) + { + FileTransferParam *transfer = proto->transfers.at(fileNumber); + + switch (type) + { + case TOX_FILECONTROL_ACCEPT: + proto->ForkThread(&CToxProto::SendFileAsync, transfer); + proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)fileNumber, 0); + break; + + 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); + break; + } + } +} \ No newline at end of file diff --git a/protocols/Tox/src/tox_transfers.cpp b/protocols/Tox/src/tox_transfers.cpp deleted file mode 100644 index 51bab8aac3..0000000000 --- a/protocols/Tox/src/tox_transfers.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "common.h" - -void CToxProto::SendFileAsync(void* arg) -{ - CFile *file = (CFile*)arg; - const CFileTransfer *transfer = file->GetTransfer(); - CToxProto *proto = (CToxProto*)transfer->GetProtoInstance(); -} - -void CToxProto::SendFilesAsync(void* arg) -{ - CFileTransfer *transfer = (CFileTransfer*)arg; - - std::string toxId(getStringA(transfer->GetContactHandle(), TOX_SETTINGS_ID)); - std::vector clientId = HexStringToData(toxId); - - uint32_t number = tox_get_friend_number(tox, clientId.data()); - - for (int i = 0; transfer->GetFileCount(); i++) - { - CFile *file = transfer->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->SetNumber(hFile); - - transfer->Wait(); - } -} - -CFileTransfer *CToxProto::GetFileTransferByFileNumber(int fileNumber) -{ - for (int i = 0; fileTransfers.getCount(); i++) - { - if (fileTransfers[i]->HasFile(fileNumber)) - { - return fileTransfers[i]; - } - } - return NULL; -} \ No newline at end of file diff --git a/protocols/Tox/src/tox_utils.cpp b/protocols/Tox/src/tox_utils.cpp index 5964177965..80d8cdd0e9 100644 --- a/protocols/Tox/src/tox_utils.cpp +++ b/protocols/Tox/src/tox_utils.cpp @@ -71,32 +71,6 @@ HANDLE CToxProto::AddDbEvent(MCONTACT hContact, WORD type, DWORD timestamp, DWOR return db_event_add(hContact, &dbei); } -void CToxProto::RaiseAuthRequestEvent(DWORD timestamp, const char* toxId, const char* reason) -{ - MCONTACT hContact = this->AddContact(toxId); - - /*blob is: 0(DWORD), hContact(DWORD), nick(ASCIIZ), firstName(ASCIIZ), lastName(ASCIIZ), sid(ASCIIZ), reason(ASCIIZ)*/ - DWORD cbBlob = (DWORD) - (sizeof(DWORD)* 2 + - strlen(toxId) + - strlen(reason) + - 5); - - PBYTE pBlob, pCurBlob; - pCurBlob = pBlob = (PBYTE)mir_calloc(cbBlob); - - *((PDWORD)pCurBlob) = 0; - pCurBlob += sizeof(DWORD); - *((PDWORD)pCurBlob) = (DWORD)hContact; - pCurBlob += sizeof(DWORD); - pCurBlob += 3; - strcpy((char *)pCurBlob, toxId); - pCurBlob += strlen(toxId) + 1; - strcpy((char *)pCurBlob, reason); - - AddDbEvent(hContact, EVENTTYPE_AUTHREQUEST, timestamp, DBEF_UTF, cbBlob, pBlob); -} - std::vector CToxProto::HexStringToData(std::string hex) { std::stringstream ss; diff --git a/protocols/Tox/src/version.h b/protocols/Tox/src/version.h index 2eee3dc6b1..15c8ad26d7 100644 --- a/protocols/Tox/src/version.h +++ b/protocols/Tox/src/version.h @@ -1,7 +1,7 @@ #define __MAJOR_VERSION 0 #define __MINOR_VERSION 11 #define __RELEASE_NUM 0 -#define __BUILD_NUM 2 +#define __BUILD_NUM 3 #include -- cgit v1.2.3