diff options
| -rw-r--r-- | protocols/Tox/Tox_12.vcxproj | 1 | ||||
| -rw-r--r-- | protocols/Tox/Tox_12.vcxproj.filters | 3 | ||||
| -rw-r--r-- | protocols/Tox/bin/x64/libtox.dll | bin | 3959506 -> 3959539 bytes | |||
| -rw-r--r-- | protocols/Tox/bin/x86/libtox.dll | bin | 3301258 -> 3301804 bytes | |||
| -rw-r--r-- | protocols/Tox/include/tox.h | 25 | ||||
| -rw-r--r-- | protocols/Tox/src/common.h | 3 | ||||
| -rw-r--r-- | protocols/Tox/src/tox_account.cpp | 19 | ||||
| -rw-r--r-- | protocols/Tox/src/tox_address.h | 150 | ||||
| -rw-r--r-- | protocols/Tox/src/tox_avatars.cpp | 4 | ||||
| -rw-r--r-- | protocols/Tox/src/tox_contacts.cpp | 122 | ||||
| -rw-r--r-- | protocols/Tox/src/tox_messages.cpp | 20 | ||||
| -rw-r--r-- | protocols/Tox/src/tox_profile.cpp | 9 | ||||
| -rw-r--r-- | protocols/Tox/src/tox_proto.cpp | 47 | ||||
| -rw-r--r-- | protocols/Tox/src/tox_proto.h | 20 | ||||
| -rw-r--r-- | protocols/Tox/src/tox_search.cpp | 42 | ||||
| -rw-r--r-- | protocols/Tox/src/tox_transfer.cpp | 178 | ||||
| -rw-r--r-- | protocols/Tox/src/tox_transfer.h | 35 | ||||
| -rw-r--r-- | protocols/Tox/src/tox_utils.cpp | 37 | 
18 files changed, 425 insertions, 290 deletions
diff --git a/protocols/Tox/Tox_12.vcxproj b/protocols/Tox/Tox_12.vcxproj index c1e0ab8b2e..c29ce07566 100644 --- a/protocols/Tox/Tox_12.vcxproj +++ b/protocols/Tox/Tox_12.vcxproj @@ -199,6 +199,7 @@    <ItemGroup>
      <ClInclude Include="src\common.h" />
      <ClInclude Include="src\resource.h" />
 +    <ClInclude Include="src\tox_address.h" />
      <ClInclude Include="src\tox_bootstrap.h" />
      <ClInclude Include="src\tox_dns.h" />
      <ClInclude Include="src\tox_proto.h" />
 diff --git a/protocols/Tox/Tox_12.vcxproj.filters b/protocols/Tox/Tox_12.vcxproj.filters index fee1c08363..0a3ec927ab 100644 --- a/protocols/Tox/Tox_12.vcxproj.filters +++ b/protocols/Tox/Tox_12.vcxproj.filters @@ -36,6 +36,9 @@      <ClInclude Include="src\tox_transfer.h">
        <Filter>Header Files</Filter>
      </ClInclude>
 +    <ClInclude Include="src\tox_address.h">
 +      <Filter>Header Files</Filter>
 +    </ClInclude>
    </ItemGroup>
    <ItemGroup>
      <ClCompile Include="src\tox_proto.cpp">
 diff --git a/protocols/Tox/bin/x64/libtox.dll b/protocols/Tox/bin/x64/libtox.dll Binary files differindex 6c68460b7c..dfe99f697f 100644 --- a/protocols/Tox/bin/x64/libtox.dll +++ b/protocols/Tox/bin/x64/libtox.dll diff --git a/protocols/Tox/bin/x86/libtox.dll b/protocols/Tox/bin/x86/libtox.dll Binary files differindex 39f1a65585..dca28deeaa 100644 --- a/protocols/Tox/bin/x86/libtox.dll +++ b/protocols/Tox/bin/x86/libtox.dll diff --git a/protocols/Tox/include/tox.h b/protocols/Tox/include/tox.h index db1b10331c..ee678cc1f5 100644 --- a/protocols/Tox/include/tox.h +++ b/protocols/Tox/include/tox.h @@ -38,11 +38,14 @@ extern "C" {  #define TOX_MAX_STATUSMESSAGE_LENGTH 1007  #define TOX_MAX_FRIENDREQUEST_LENGTH 1016 -#define TOX_CLIENT_ID_SIZE 32 +#define TOX_PUBLIC_KEY_SIZE 32 +/* TODO: remove */ +#define TOX_CLIENT_ID_SIZE TOX_PUBLIC_KEY_SIZE +  #define TOX_AVATAR_MAX_DATA_LENGTH 16384  #define TOX_HASH_LENGTH /*crypto_hash_sha256_BYTES*/ 32 -#define TOX_FRIEND_ADDRESS_SIZE (TOX_CLIENT_ID_SIZE + sizeof(uint32_t) + sizeof(uint16_t)) +#define TOX_FRIEND_ADDRESS_SIZE (TOX_PUBLIC_KEY_SIZE + sizeof(uint32_t) + sizeof(uint16_t))  #define TOX_ENABLE_IPV6_DEFAULT 1 @@ -97,7 +100,7 @@ typedef struct Tox Tox;   */  /*  return TOX_FRIEND_ADDRESS_SIZE byte address to give to others. - * format: [client_id (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)] + * format: [public_key (32 bytes)][nospam number (4 bytes)][checksum (2 bytes)]   */  void tox_get_address(const Tox *tox, uint8_t *address); @@ -124,18 +127,18 @@ int32_t tox_add_friend(Tox *tox, const uint8_t *address, const uint8_t *data, ui   *  return the friend number if success.   *  return -1 if failure.   */ -int32_t tox_add_friend_norequest(Tox *tox, const uint8_t *client_id); +int32_t tox_add_friend_norequest(Tox *tox, const uint8_t *public_key);  /*  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); +int32_t tox_get_friend_number(const Tox *tox, const uint8_t *public_key); -/* Copies the public key associated to that friend id into client_id buffer. - * Make sure that client_id is of size CLIENT_ID_SIZE. +/* Copies the public key associated to that friend id into public_key buffer. + * Make sure that public_key is of size TOX_PUBLIC_KEY_SIZE.   *  return 0 if success.   *  return -1 if failure.   */ -int tox_get_client_id(const Tox *tox, int32_t friendnumber, uint8_t *client_id); +int tox_get_client_id(const Tox *tox, int32_t friendnumber, uint8_t *public_key);  /* Remove a friend.   * @@ -500,13 +503,13 @@ int tox_del_groupchat(Tox *tox, int groupnumber);   */  int tox_group_peername(const Tox *tox, int groupnumber, int peernumber, uint8_t *name); -/* Copy the public key of peernumber who is in groupnumber to pk. - * pk must be TOX_CLIENT_ID_SIZE long. +/* Copy the public key of peernumber who is in groupnumber to public_key. + * public_key must be TOX_PUBLIC_KEY_SIZE long.   *   * returns 0 on success   * returns -1 on failure   */ -int tox_group_peer_pubkey(const Tox *tox, int groupnumber, int peernumber, uint8_t *pk); +int tox_group_peer_pubkey(const Tox *tox, int groupnumber, int peernumber, uint8_t *public_key);  /* invite friendnumber to groupnumber   * return 0 on success diff --git a/protocols/Tox/src/common.h b/protocols/Tox/src/common.h index 1250b10fd7..93b22b718e 100644 --- a/protocols/Tox/src/common.h +++ b/protocols/Tox/src/common.h @@ -9,7 +9,7 @@  #include <string>
  #include <sstream>
  #include <iomanip>
 -#include <vector>
 +//#include <vector>
  #include <regex>
  #include <map>
 @@ -37,6 +37,7 @@  #include "version.h"
  #include "resource.h"
 +#include "tox_address.h"
  #include "tox_transfer.h"
  #include "tox_proto.h"
 diff --git a/protocols/Tox/src/tox_account.cpp b/protocols/Tox/src/tox_account.cpp index 3b4f61b32b..2aa3081442 100644 --- a/protocols/Tox/src/tox_account.cpp +++ b/protocols/Tox/src/tox_account.cpp @@ -84,15 +84,14 @@ bool CToxProto::InitToxCore()  		tox_callback_avatar_info(tox, OnGotFriendAvatarInfo, this);
  		tox_callback_avatar_data(tox, OnGotFriendAvatarData, this);
 -		std::vector<uint8_t> pubKey(TOX_FRIEND_ADDRESS_SIZE);
 -		tox_get_address(tox, &pubKey[0]);
 -		std::string address = DataToHexString(pubKey);
 -		setString(NULL, TOX_SETTINGS_ID, address.c_str());
 +		uint8_t data[TOX_FRIEND_ADDRESS_SIZE];
 +		tox_get_address(tox, data);
 +		ToxHexAddress address(data, TOX_FRIEND_ADDRESS_SIZE);
 +		setString(NULL, TOX_SETTINGS_ID, address);
  		int size = tox_get_self_name_size(tox);
 -		std::vector<uint8_t> username(size);
 -		tox_get_self_name(tox, &username[0]);
 -		std::string nick(username.begin(), username.end());
 +		std::string nick(size, 0);
 +		tox_get_self_name(tox, (uint8_t*)nick.data());
  		setWString("Nick", ptrW(Utf8DecodeW(nick.c_str())));
  		std::tstring avatarPath = GetAvatarFilePath();
 @@ -117,7 +116,7 @@ bool CToxProto::InitToxCore()  void CToxProto::UninitToxCore()
  {
  	ptrA nickname(mir_utf8encodeW(ptrT(getTStringA("Nick"))));
 -	tox_set_name(tox, (uint8_t*)(char*)nickname, (uint16_t)strlen(nickname));
 +	tox_set_name(tox, (uint8_t*)(char*)nickname, mir_strlen(nickname));
  	SaveToxProfile();
  	if (password != NULL)
 @@ -143,8 +142,6 @@ void CToxProto::DoBootstrap()  void CToxProto::DoTox()
  {
  	tox_do(tox);
 -
 -	//PulseEvent(hToxEvent);
  	uint32_t interval = tox_do_interval(tox);
  	Sleep(interval);
  }
 @@ -178,7 +175,7 @@ void CToxProto::PollingThread(void*)  				isConnected = true;
  				debugLogA("CToxProto::PollingThread: successfuly connected to DHT");
 -				LoadFriendList();
 +				ForkThread(&CToxProto::LoadFriendList, NULL);
  				debugLogA("CToxProto::PollingThread: changing status from %i to %i", ID_STATUS_CONNECTING, m_iDesiredStatus);
  				m_iStatus = m_iDesiredStatus;
 diff --git a/protocols/Tox/src/tox_address.h b/protocols/Tox/src/tox_address.h new file mode 100644 index 0000000000..b8ceccefae --- /dev/null +++ b/protocols/Tox/src/tox_address.h @@ -0,0 +1,150 @@ +#ifndef _TOX_ADDRESS_H_
 +#define _TOX_ADDRESS_H_
 +
 +class ToxHexAddress;
 +class ToxBinAddress;
 +
 +class ToxHexAddress
 +{
 +private:
 +	std::string hexData;
 +public:
 +	ToxHexAddress(const char *hex) : hexData(hex) { }
 +	ToxHexAddress(const std::string &hex) : hexData(hex) { }
 +	ToxHexAddress(const ToxHexAddress &address) : hexData(address.hexData) { }
 +	ToxHexAddress(const std::vector<uint8_t> &bin)
 +	{
 +		this->ToxHexAddress::ToxHexAddress(bin.data(), bin.size());
 +	}
 +	ToxHexAddress(const uint8_t *bin, int size = TOX_FRIEND_ADDRESS_SIZE)
 +	{
 +		char *hex = (char*)mir_alloc(size * 2 + 1);
 +		hexData = bin2hex(bin, size, hex);
 +		std::transform(hexData.begin(), hexData.end(), hexData.begin(), ::toupper);
 +		mir_free(hex);
 +	}
 +	const size_t GetLength() const
 +	{
 +		return hexData.length();
 +	}
 +	const ToxHexAddress GetPubKey() const
 +	{
 +		ToxHexAddress pubKey = hexData.substr(0, TOX_PUBLIC_KEY_SIZE * 2).c_str();
 +		return pubKey;
 +	}
 +	operator const char*() const
 +	{
 +		return hexData.c_str();
 +	}
 +	ToxBinAddress ToBin() const;
 +};
 +
 +class ToxBinAddress
 +{
 +private:
 +	std::vector<uint8_t> binData;
 +public:
 +	ToxBinAddress(const ToxBinAddress &address) : binData(address.binData) { }
 +	ToxBinAddress(const std::vector<uint8_t> &bin) : binData(bin) { }
 +	ToxBinAddress(const uint8_t *bin, int size = TOX_FRIEND_ADDRESS_SIZE) : binData(bin, bin + size) { }
 +	ToxBinAddress(const std::string &hex)
 +	{
 +		this->ToxBinAddress::ToxBinAddress(hex.c_str());
 +	}
 +	ToxBinAddress(const char *hex)
 +	{
 +		char *endptr;
 +		const char *pos = hex;
 +		int size = mir_strlen(hex) / 2;
 +		uint8_t *result = (uint8_t*)mir_alloc(size);
 +		for (int i = 0; i < size; i++)
 +		{
 +			char buf[5] = { '0', 'x', pos[0], pos[1], 0 };
 +			binData.push_back((uint8_t)strtol(buf, &endptr, 0));
 +			pos += 2;
 +		}
 +	}
 +	const ToxBinAddress GetPubKey() const
 +	{
 +		ToxBinAddress pubKey(binData.data(), TOX_PUBLIC_KEY_SIZE);
 +		return pubKey;
 +	}
 +	operator const uint8_t*() const
 +	{
 +		return binData.data();
 +	}
 +	ToxHexAddress ToHex() const
 +	{
 +		ToxHexAddress hex(binData.data(), binData.size());
 +		return hex;
 +	}
 +};
 +
 +ToxBinAddress ToxHexAddress::ToBin() const
 +{
 +	ToxBinAddress bin(hexData.c_str());
 +	return bin;
 +}
 +
 +/*class ToxAddress
 +{
 +private:
 +	std::string hexData;
 +
 +	class ToxBytes
 +	{
 +	private:
 +		uint8_t *bytes;
 +
 +	public:
 +		ToxBytes(uint8_t *bytes) : bytes(bytes) { }
 +		~ToxBytes() { if (bytes) mir_free(bytes); }
 +
 +		operator const uint8_t*() { return bytes; }
 +	};
 +
 +public:
 +	ToxAddress(const char *hex) : hexData(hex) { }
 +	ToxAddress(const std::string &hex) : hexData(hex) { }
 +	ToxAddress(const ToxAddress &address) : hexData(address.hexData) { }
 +	ToxAddress(const uint8_t *bin, int size = TOX_FRIEND_ADDRESS_SIZE)
 +		//: binData(bin, bin + size)
 +	{
 +		char *hex = (char*)mir_alloc(size * 2 + 1);
 +		std::string hexData = bin2hex(bin, size, hex);
 +		std::transform(hexData.begin(), hexData.end(), hexData.begin(), ::toupper);
 +		//mir_free(hex);
 +	}
 +
 +	~ToxAddress()
 +	{
 +		int i = 0;
 +	}
 +
 +	operator const char*() const
 +	{
 +		return hexData.c_str();
 +	}
 +
 +	ToxBytes AsBytes() const
 +	{
 +		char *endptr;
 +		const char *pos = hexData.c_str();
 +		int size = hexData.length() / 2;
 +		uint8_t *result = (uint8_t*)mir_alloc(size);
 +		for (int i = 0; i < size; i++)
 +		{
 +			char buf[5] = { '0', 'x', pos[0], pos[1], 0 };
 +			result[i] = (uint8_t)strtol(buf, &endptr, 0);
 +			pos += 2;
 +		}
 +		return ToxBytes(result);
 +	}
 +
 +	std::string AsPubKey() const
 +	{
 +		return hexData.substr(0, TOX_PUBLIC_KEY_SIZE * 2).c_str();
 +	}
 +};*/
 +
 +#endif //_TOX_ADDRESS_H_
\ No newline at end of file diff --git a/protocols/Tox/src/tox_avatars.cpp b/protocols/Tox/src/tox_avatars.cpp index b69c462559..8f4410c5f3 100644 --- a/protocols/Tox/src/tox_avatars.cpp +++ b/protocols/Tox/src/tox_avatars.cpp @@ -196,7 +196,7 @@ void CToxProto::OnGotFriendAvatarInfo(Tox *tox, int32_t number, uint8_t format,  {
  	CToxProto *proto = (CToxProto*)arg;
 -	MCONTACT hContact = proto->FindContact(number);
 +	MCONTACT hContact = proto->GetContact(number);
  	if (hContact)
  	{
  		std::tstring path = proto->GetAvatarFilePath(hContact);
 @@ -232,7 +232,7 @@ void CToxProto::OnGotFriendAvatarData(Tox *tox, int32_t number, uint8_t format,  {
  	CToxProto *proto = (CToxProto*)arg;
 -	MCONTACT hContact = proto->FindContact(number);
 +	MCONTACT hContact = proto->GetContact(number);
  	if (hContact)
  	{
  		db_set_blob(hContact, proto->m_szModuleName, TOX_SETTINGS_AVATAR_HASH, hash, TOX_HASH_LENGTH);
 diff --git a/protocols/Tox/src/tox_contacts.cpp b/protocols/Tox/src/tox_contacts.cpp index 30c9fcc486..0808837727 100644 --- a/protocols/Tox/src/tox_contacts.cpp +++ b/protocols/Tox/src/tox_contacts.cpp @@ -41,14 +41,15 @@ MCONTACT CToxProto::GetContactFromAuthEvent(MEVENT hEvent)  	return DbGetAuthEventContact(&dbei);
  }
 -bool CToxProto::IsMe(const std::string &id)
 +MCONTACT CToxProto::GetContact(const int friendNumber)
  {
 -	std::string ownId = getStringA(NULL, TOX_SETTINGS_ID);
 -
 -	return strnicmp(id.c_str(), ownId.c_str(), TOX_CLIENT_ID_SIZE) == 0;
 +	uint8_t data[TOX_PUBLIC_KEY_SIZE];
 +	tox_get_client_id(tox, friendNumber, data);
 +	ToxHexAddress pubKey(data, TOX_PUBLIC_KEY_SIZE);
 +	return GetContact(pubKey);
  }
 -MCONTACT CToxProto::FindContact(const std::string &id)
 +MCONTACT CToxProto::GetContact(const char *pubKey)
  {
  	MCONTACT hContact = NULL;
  	for (hContact = db_find_first(m_szModuleName); hContact; hContact = db_find_next(hContact, m_szModuleName))
 @@ -56,24 +57,14 @@ MCONTACT CToxProto::FindContact(const std::string &id)  		DBVARIANT dbv;
  		if (!db_get(hContact, m_szModuleName, TOX_SETTINGS_ID, &dbv))
  		{
 -			std::string clientId;
 -
 -			// temporary code for contact id conversion
 -			if (dbv.type == DBVT_BLOB)
 +			std::string contactPubKey;
 +			if (dbv.type == DBVT_ASCIIZ)
  			{
 -				std::vector<uint8_t> pubKey(dbv.cpbVal);
 -				memcpy(&pubKey[0], dbv.pbVal, dbv.cpbVal);
 -				clientId = DataToHexString(pubKey);
 -				delSetting(hContact, TOX_SETTINGS_ID);
 -				setString(hContact, TOX_SETTINGS_ID, clientId.c_str());
 -			}
 -			else if (dbv.type == DBVT_ASCIIZ)
 -			{
 -				clientId = dbv.pszVal;
 +				contactPubKey = dbv.pszVal;
  			}
  			db_free(&dbv);
 -
 -			if (mir_strcmpi(id.c_str(), clientId.c_str()) == 0)
 +			// check only public key part of address
 +			if (strnicmp(pubKey, contactPubKey.c_str(), TOX_PUBLIC_KEY_SIZE) == 0)
  			{
  				break;
  			}
 @@ -82,25 +73,16 @@ MCONTACT CToxProto::FindContact(const std::string &id)  	return hContact;
  }
 -MCONTACT CToxProto::FindContact(const int friendNumber)
 +MCONTACT CToxProto::AddContact(const char *address, const std::tstring &dnsId, bool isTemporary)
  {
 -	std::vector<uint8_t> clientId(TOX_CLIENT_ID_SIZE);
 -	tox_get_client_id(tox, friendNumber, clientId.data());
 -
 -	std::string id = DataToHexString(clientId);
 -
 -	return FindContact(id);
 -}
 -
 -MCONTACT CToxProto::AddContact(const std::string &id, const std::tstring &dnsId, bool isTemporary)
 -{
 -	MCONTACT hContact = FindContact(id);
 +	MCONTACT hContact = GetContact(address);
  	if (!hContact)
  	{
  		hContact = (MCONTACT)CallService(MS_DB_CONTACT_ADD, 0, 0);
  		CallService(MS_PROTO_ADDTOCONTACT, hContact, (LPARAM)m_szModuleName);
 -		setString(hContact, TOX_SETTINGS_ID, id.c_str());
 +		setString(hContact, TOX_SETTINGS_ID, address);
 +
  		if (!dnsId.empty())
  		{
  			setTString(hContact, TOX_SETTINGS_DNS, dnsId.c_str());
 @@ -124,7 +106,7 @@ MCONTACT CToxProto::AddContact(const std::string &id, const std::tstring &dnsId,  	return hContact;
  }
 -void CToxProto::LoadFriendList()
 +void CToxProto::LoadFriendList(void*)
  {
  	uint32_t count = tox_count_friendlist(tox);
  	if (count > 0)
 @@ -132,21 +114,24 @@ void CToxProto::LoadFriendList()  		int32_t *friends = (int32_t*)mir_alloc(count * sizeof(int32_t));
  		tox_get_friendlist(tox, friends, count);
 -		std::vector<uint8_t> id(TOX_CLIENT_ID_SIZE);
 +		uint8_t data[TOX_PUBLIC_KEY_SIZE];
  		for (uint32_t i = 0; i < count; ++i)
  		{
 -			tox_get_client_id(tox, friends[i], id.data());
 -			MCONTACT hContact = AddContact(DataToHexString(id), _T(""));
 +			tox_get_client_id(tox, friends[i], data);
 +			ToxHexAddress pubKey(data, TOX_PUBLIC_KEY_SIZE);
 +			MCONTACT hContact = AddContact(pubKey, _T(""));
  			if (hContact)
  			{
  				delSetting(hContact, "Auth");
  				delSetting(hContact, "Grant");
  				int size = tox_get_name_size(tox, friends[i]);
 -				std::vector<uint8_t> username(size);
 -				tox_get_name(tox, friends[i], &username[0]);
 -				std::string nick(username.begin(), username.end());
 -				setWString(hContact, "Nick", ptrW(Utf8DecodeW(nick.c_str())));
 +				if (size != TOX_ERROR)
 +				{
 +					std::string nick(size, 0);
 +					tox_get_name(tox, friends[i], (uint8_t*)nick.data());
 +					setWString(hContact, "Nick", ptrW(Utf8DecodeW(nick.c_str())));
 +				}
  				uint64_t timestamp = tox_get_last_online(tox, friends[i]);
  				if (timestamp)
 @@ -171,10 +156,8 @@ int CToxProto::OnContactDeleted(MCONTACT hContact, LPARAM lParam)  		return 1;
  	}
 -	std::string id = getStringA(hContact, TOX_SETTINGS_ID);
 -	std::vector<uint8_t> clientId = HexStringToData(id);
 -
 -	uint32_t number = tox_get_friend_number(tox, clientId.data());
 +	ToxBinAddress pubKey = ptrA(getStringA(hContact, TOX_SETTINGS_ID));
 +	int32_t number = tox_get_friend_number(tox, pubKey);
  	if (number == TOX_ERROR || tox_del_friend(tox, number) == TOX_ERROR)
  	{
  		return 1;
 @@ -183,15 +166,12 @@ int CToxProto::OnContactDeleted(MCONTACT hContact, LPARAM lParam)  	return 0;
  }
 -void CToxProto::OnFriendRequest(Tox *tox, const uint8_t *address, const uint8_t *message, const uint16_t messageSize, void *arg)
 +void CToxProto::OnFriendRequest(Tox *tox, const uint8_t *data, const uint8_t *message, const uint16_t messageSize, void *arg)
  {
  	CToxProto *proto = (CToxProto*)arg;
 -	// trim tox address to tox id
 -	std::vector<uint8_t> clientId(address, address + TOX_CLIENT_ID_SIZE);
 -	std::string id = proto->DataToHexString(clientId);
 -
 -	MCONTACT hContact = proto->AddContact(id, _T(""));
 +	ToxHexAddress address(data, TOX_FRIEND_ADDRESS_SIZE);
 +	MCONTACT hContact = proto->AddContact(address, _T(""));
  	if (!hContact)
  	{
  		return;
 @@ -202,7 +182,7 @@ void CToxProto::OnFriendRequest(Tox *tox, const uint8_t *address, const uint8_t  	PROTORECVEVENT pre = { 0 };
  	pre.flags = PREF_UTF;
  	pre.timestamp = time(NULL);
 -	pre.lParam = (DWORD)(sizeof(DWORD)* 2 + id.length() + messageSize + 5);
 +	pre.lParam = (DWORD)(sizeof(DWORD) * 2 + address.GetLength() + messageSize + 5);
  	/*blob is: 0(DWORD), hContact(DWORD), nick(ASCIIZ), firstName(ASCIIZ), lastName(ASCIIZ), id(ASCIIZ), reason(ASCIIZ)*/
  	PBYTE pBlob, pCurBlob;
 @@ -213,9 +193,9 @@ void CToxProto::OnFriendRequest(Tox *tox, const uint8_t *address, const uint8_t  	*((PDWORD)pCurBlob) = (DWORD)hContact;
  	pCurBlob += sizeof(DWORD);
  	pCurBlob += 3;
 -	strcpy((char *)pCurBlob, id.c_str());
 -	pCurBlob += id.length() + 1;
 -	strcpy((char *)pCurBlob, (char*)message);
 +	mir_strcpy((char *)pCurBlob, address);
 +	pCurBlob += address.GetLength() + 1;
 +	mir_strcpy((char *)pCurBlob, (char*)message);
  	pre.szMessage = (char*)pBlob;
  	ProtoChainRecv(hContact, PSR_AUTH, 0, (LPARAM)&pre);
 @@ -225,7 +205,7 @@ void CToxProto::OnFriendNameChange(Tox *tox, const int friendNumber, const uint8  {
  	CToxProto *proto = (CToxProto*)arg;
 -	MCONTACT hContact = proto->FindContact(friendNumber);
 +	MCONTACT hContact = proto->GetContact(friendNumber);
  	if (hContact)
  	{
  		proto->setString(hContact, "Nick", (char*)name);
 @@ -236,7 +216,7 @@ void CToxProto::OnStatusMessageChanged(Tox *tox, const int friendNumber, const u  {
  	CToxProto *proto = (CToxProto*)arg;
 -	MCONTACT hContact = proto->FindContact(friendNumber);
 +	MCONTACT hContact = proto->GetContact(friendNumber);
  	if (hContact)
  	{
  		ptrW statusMessage(mir_utf8decodeW((char*)message));
 @@ -248,7 +228,7 @@ void CToxProto::OnUserStatusChanged(Tox *tox, int32_t friendNumber, uint8_t user  {
  	CToxProto *proto = (CToxProto*)arg;
 -	MCONTACT hContact = proto->FindContact(friendNumber);
 +	MCONTACT hContact = proto->GetContact(friendNumber);
  	if (hContact)
  	{
  		TOX_USERSTATUS userstatus = (TOX_USERSTATUS)usertatus;
 @@ -261,9 +241,7 @@ void CToxProto::OnConnectionStatusChanged(Tox *tox, const int friendNumber, cons  {
  	CToxProto *proto = (CToxProto*)arg;
 -	//mir_cslock lock(proto->toxLock);
 -
 -	MCONTACT hContact = proto->FindContact(friendNumber);
 +	MCONTACT hContact = proto->GetContact(friendNumber);
  	if (hContact)
  	{
  		int newStatus = status ? ID_STATUS_ONLINE : ID_STATUS_OFFLINE;
 @@ -273,24 +251,34 @@ void CToxProto::OnConnectionStatusChanged(Tox *tox, const int friendNumber, cons  			tox_send_avatar_info(proto->tox, friendNumber);
  			proto->delSetting(hContact, "Auth");
 -			for (int i = 0; i < proto->transfers->Count(); i++)
 +			for (size_t i = 0; i < proto->transfers->Count(); i++)
  			{
  				// only for receiving
 -				FileTransferParam *transfer = proto->transfers->At(i);
 +				FileTransferParam *transfer = proto->transfers->GetAt(i);
  				if (transfer->friendNumber == friendNumber && transfer->GetDirection() == 1)
  				{
 -					transfer->Resume(tox);
 +					if (transfer->Resume(tox) == TOX_ERROR)
 +					{
 +						transfer->Cancel(tox);
 +						proto->debugLogA("CToxProto::OnConnectionStatusChanged: failed to resuming of file (%d)",
 +							transfer->pfts.currentFileProgress, transfer->pfts.currentFileSize, transfer->fileNumber);
 +						continue;
 +					}
 +					proto->debugLogA("CToxProto::OnConnectionStatusChanged: ask to resume the receiving at %llu of %llu of file (%d)",
 +						transfer->pfts.currentFileProgress, transfer->pfts.currentFileSize, transfer->fileNumber);
  				}
  			}
  		}
  		else
  		{
 -			for (int i = 0; i < proto->transfers->Count(); i++)
 +			for (size_t i = 0; i < proto->transfers->Count(); i++)
  			{
 -				FileTransferParam *transfer = proto->transfers->At(i);
 +				FileTransferParam *transfer = proto->transfers->GetAt(i);
  				if (transfer->friendNumber == friendNumber)
  				{
 -					transfer->status = PAUSED;
 +					mir_cslock(transfer->fileLock);
 +
 +					transfer->status = BROKEN;
  				}
  			}
  		}
 diff --git a/protocols/Tox/src/tox_messages.cpp b/protocols/Tox/src/tox_messages.cpp index 51f255b546..a050b7f962 100644 --- a/protocols/Tox/src/tox_messages.cpp +++ b/protocols/Tox/src/tox_messages.cpp @@ -4,7 +4,7 @@ void CToxProto::OnFriendMessage(Tox *tox, const int number, const uint8_t *messa  {
  	CToxProto *proto = (CToxProto*)arg;
 -	MCONTACT hContact = proto->FindContact(number);
 +	MCONTACT hContact = proto->GetContact(number);
  	if (hContact)
  	{
  		PROTORECVEVENT recv = { 0 };
 @@ -20,7 +20,7 @@ void CToxProto::OnFriendAction(Tox *tox, const int number, const uint8_t *action  {
  	CToxProto *proto = (CToxProto*)arg;
 -	MCONTACT hContact = proto->FindContact(number);
 +	MCONTACT hContact = proto->GetContact(number);
  	if (hContact)
  	{
  		proto->AddDbEvent(
 @@ -35,9 +35,7 @@ void CToxProto::OnFriendAction(Tox *tox, const int number, const uint8_t *action  int __cdecl CToxProto::SendMsg(MCONTACT hContact, int flags, const char* msg)
  {
 -	std::string id = getStringA(hContact, TOX_SETTINGS_ID);
 -	std::vector<uint8_t> clientId = HexStringToData(id);
 -	uint32_t number = tox_get_friend_number(tox, clientId.data());
 +	uint32_t number = 0;// getDword(hContact, TOX_SETTINGS_NUMBER, TOX_ERROR);
  	if (number == TOX_ERROR)
  	{
  		debugLogA("CToxProto::SendMsg: failed to get friend number");
 @@ -48,11 +46,11 @@ int __cdecl CToxProto::SendMsg(MCONTACT hContact, int flags, const char* msg)  	{
  		if (strncmp(msg, "/me ", 4) != 0)
  		{
 -			result = tox_send_message(tox, number, (uint8_t*)msg, (uint16_t)strlen(msg));
 +			result = tox_send_message(tox, number, (uint8_t*)msg, mir_strlen(msg));
  		}
  		else
  		{
 -			result = tox_send_action(tox, number, (uint8_t*)&msg[4], (uint16_t)(strlen(msg) - 4));
 +			result = tox_send_action(tox, number, (uint8_t*)&msg[4], mir_strlen(msg) - 4);
  		}
  	}
 @@ -68,7 +66,7 @@ void CToxProto::OnReadReceipt(Tox *tox, int32_t number, uint32_t receipt, void *  {
  	CToxProto *proto = (CToxProto*)arg;
 -	MCONTACT hContact = proto->FindContact(number);
 +	MCONTACT hContact = proto->GetContact(number);
  	if (hContact)
  	{
  		proto->ProtoBroadcastAck(
 @@ -106,7 +104,7 @@ void CToxProto::OnTypingChanged(Tox *tox, const int number, uint8_t isTyping, vo  {
  	CToxProto *proto = (CToxProto*)arg;
 -	MCONTACT hContact = proto->FindContact(number);
 +	MCONTACT hContact = proto->GetContact(number);
  	if (hContact)
  	{
  		CallService(MS_PROTO_CONTACTISTYPING, hContact, (LPARAM)isTyping);
 @@ -117,9 +115,7 @@ int __cdecl CToxProto::UserIsTyping(MCONTACT hContact, int type)  {
  	if (hContact && IsOnline())
  	{
 -		std::string id = getStringA(hContact, TOX_SETTINGS_ID);
 -		std::vector<uint8_t> clientId = HexStringToData(id);
 -		uint32_t number = tox_get_friend_number(tox, clientId.data());
 +		uint32_t number = 0;//getDword(hContact, TOX_SETTINGS_NUMBER, TOX_ERROR);
  		if (number >= 0)
  		{
  			tox_set_user_is_typing(tox, number, type);
 diff --git a/protocols/Tox/src/tox_profile.cpp b/protocols/Tox/src/tox_profile.cpp index 898899bff1..d169b21f78 100644 --- a/protocols/Tox/src/tox_profile.cpp +++ b/protocols/Tox/src/tox_profile.cpp @@ -31,8 +31,8 @@ bool CToxProto::LoadToxProfile()  	}
  	fseek(profile, 0, SEEK_END);
 -	size_t size = ftell(profile);
 -	fseek(profile, 0, SEEK_SET);
 +	size_t size = _ftelli64(profile);
 +	rewind(profile);
  	if (size == 0)
  	{
  		fclose(profile);
 @@ -41,8 +41,7 @@ bool CToxProto::LoadToxProfile()  	}
  	uint8_t *data = (uint8_t*)mir_calloc(size);
 -	size_t read = fread((char*)data, sizeof(char), size, profile);
 -	if (size != read)
 +	if (fread((char*)data, sizeof(char), size, profile) != size)
  	{
  		fclose(profile);
  		debugLogA("CToxProto::LoadToxData: could not read tox profile");
 @@ -66,7 +65,7 @@ bool CToxProto::LoadToxProfile()  			}
  		}
 -		if (tox_encrypted_load(tox, data, size, (uint8_t*)password, strlen(password)) == TOX_ERROR)
 +		if (tox_encrypted_load(tox, data, size, (uint8_t*)password, mir_strlen(password)) == TOX_ERROR)
  		{
  			debugLogA("CToxProto::LoadToxData: could not decrypt tox profile");
  			mir_free(data);
 diff --git a/protocols/Tox/src/tox_proto.cpp b/protocols/Tox/src/tox_proto.cpp index 36dba649ea..bf122b72e7 100644 --- a/protocols/Tox/src/tox_proto.cpp +++ b/protocols/Tox/src/tox_proto.cpp @@ -48,8 +48,6 @@ CToxProto::CToxProto(const char* protoName, const TCHAR* userName) :  	// transfers
  	transfers = new CTransferList();
 -
 -	hToxEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  }
  CToxProto::~CToxProto()
 @@ -83,22 +81,26 @@ DWORD_PTR __cdecl CToxProto::GetCaps(int type, MCONTACT hContact)  	return 0;
  }
 -MCONTACT __cdecl CToxProto::AddToList(int flags, PROTOSEARCHRESULT* psr)
 +MCONTACT __cdecl CToxProto::AddToList(int flags, PROTOSEARCHRESULT *psr)
  {
 -	std::string address(mir_t2a(psr->id));
 -	if (IsMe(address))
 +	std::string address(ptrA(mir_t2a(psr->id)));
 +	ptrA myAddress(getStringA(NULL, TOX_SETTINGS_ID));
 +	if (strnicmp(address.c_str(), myAddress, TOX_PUBLIC_KEY_SIZE) == 0)
 +	{
 +		ShowNotification(TranslateT("You cannot add yourself to your contact list"), 0);
 +		return NULL;
 +	}
 +	MCONTACT hContact = GetContact(address.c_str());
 +	if (hContact)
  	{
 -		debugLogA("CToxProto::AddToList: you cannot add yourself to friend list");
 +		ShowNotification(TranslateT("Contact already in your contact list"), 0, hContact);
  		return NULL;
  	}
 -	// set tox address as contact id
 -	return AddContact(address, _T(""), flags & PALF_TEMPORARY);
 +	// set tox address as contact public key
 +	return AddContact(address.c_str(), _T(""), flags & PALF_TEMPORARY);
  }
 -MCONTACT __cdecl CToxProto::AddToListByEvent(int flags, int iContact, MEVENT hDbEvent)
 -{
 -	return 0;
 -}
 +MCONTACT __cdecl CToxProto::AddToListByEvent(int flags, int iContact, MEVENT hDbEvent) { return 0; }
  int __cdecl CToxProto::Authorize(MEVENT hDbEvent)
  {
 @@ -108,13 +110,16 @@ int __cdecl CToxProto::Authorize(MEVENT hDbEvent)  		return 1;
  	}
 -	std::string id = getStringA(hContact, TOX_SETTINGS_ID);
 -	std::vector<uint8_t> clientId = HexStringToData(id);
 -	if (tox_add_friend_norequest(tox, clientId.data()) != TOX_ERROR)
 +	ToxBinAddress address = ptrA(getStringA(hContact, TOX_SETTINGS_ID));
 +	ToxBinAddress pubKey = address.GetPubKey();
 +	if (tox_add_friend_norequest(tox, pubKey) == TOX_ERROR)
  	{
  		return 1;
  	}
 +	// trim address to public key
 +	setString(hContact, TOX_SETTINGS_ID, pubKey.ToHex());
 +
  	db_unset(hContact, "CList", "NotOnList");
  	delSetting(hContact, "Grant");
 @@ -132,14 +137,12 @@ int __cdecl CToxProto::AuthRequest(MCONTACT hContact, const PROTOCHAR *szMessage  {
  	ptrA reason(mir_utf8encodeW(szMessage));
 -	std::string address = getStringA(hContact, TOX_SETTINGS_ID);
 -	std::vector<uint8_t> pubKey = HexStringToData(address);
 -	int32_t number = tox_add_friend(tox, pubKey.data(), (uint8_t*)(char*)reason, (uint16_t)strlen(reason));
 +	ToxBinAddress address = ptrA(getStringA(hContact, TOX_SETTINGS_ID));
 +	int32_t number = tox_add_friend(tox, address, (uint8_t*)(char*)reason, mir_strlen(reason));
  	if (number > TOX_ERROR)
  	{
 -		// change tox address in contact id by tox id
 -		std::string id = ToxAddressToId(address);
 -		setString(hContact, TOX_SETTINGS_ID, id.c_str());
 +		// trim address to public key
 +		setString(hContact, TOX_SETTINGS_ID, address.ToHex().GetPubKey());
  		db_unset(hContact, "CList", "NotOnList");
  		delSetting(hContact, "Grant");
 @@ -260,7 +263,7 @@ int __cdecl CToxProto::SetAwayMsg(int iStatus, const PROTOCHAR *msg)  		//WaitForSingleObject(hToxEvent, INFINITE);
  		ptrA statusMessage(msg == NULL ? mir_strdup("") : mir_utf8encodeT(msg));
 -		if (tox_set_status_message(tox, (uint8_t*)(char*)statusMessage, min(TOX_MAX_STATUSMESSAGE_LENGTH, strlen(statusMessage))) == TOX_ERROR)
 +		if (tox_set_status_message(tox, (uint8_t*)(char*)statusMessage, min(TOX_MAX_STATUSMESSAGE_LENGTH, mir_strlen(statusMessage))) == TOX_ERROR)
  		{
  			debugLogA("CToxProto::SetAwayMsg: failed to set status status message %s", msg);
  		}
 diff --git a/protocols/Tox/src/tox_proto.h b/protocols/Tox/src/tox_proto.h index eab3eb509b..03fdfa1a78 100644 --- a/protocols/Tox/src/tox_proto.h +++ b/protocols/Tox/src/tox_proto.h @@ -68,7 +68,7 @@ private:  	char *password;
  	mir_cs toxLock;
  	TCHAR *accountName;
 -	HANDLE hNetlib, hPollingThread, hToxEvent;
 +	HANDLE hNetlib, hPollingThread;
  	bool isTerminated, isConnected;
  	CTransferList *transfers;
 @@ -119,18 +119,19 @@ private:  	WORD GetContactStatus(MCONTACT hContact);
  	void SetContactStatus(MCONTACT hContact, WORD status);
  	void SetAllContactsStatus(WORD status);
 -	bool IsMe(const std::string &id);
 -	MCONTACT FindContact(const std::string &id);
 -	MCONTACT FindContact(const int friendNumber);
 -	MCONTACT AddContact(const std::string &id, const std::tstring &dnsId, bool isTemporary = false);
 +
 +	MCONTACT GetContact(const int friendNumber);
 +	MCONTACT GetContact(const char *pubKey);
 +
 +	MCONTACT AddContact(const char *address, const std::tstring &dnsId, bool isTemporary = false);
  	MCONTACT GetContactFromAuthEvent(MEVENT hEvent);
 -	void LoadFriendList();
 +	void __cdecl LoadFriendList(void*);
  	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 OnFriendRequest(Tox *tox, const uint8_t *pubKey, const uint8_t *message, const uint16_t messageSize, void *arg);
  	static void OnFriendNameChange(Tox *tox, const int friendNumber, const uint8_t *name, const uint16_t nameSize, void *arg);
  	static void OnStatusMessageChanged(Tox *tox, const int friendNumber, const uint8_t* message, const uint16_t messageSize, void *arg);
  	static void OnUserStatusChanged(Tox *tox, int32_t friendNumber, uint8_t usertatus, void *arg);
 @@ -178,11 +179,6 @@ private:  	static void ShowNotification(const TCHAR *caption, const TCHAR *message, int flags = 0, MCONTACT hContact = NULL);
  	MEVENT AddDbEvent(MCONTACT hContact, WORD type, DWORD timestamp, DWORD flags, DWORD cbBlob, PBYTE pBlob);
 -	
 -	std::vector<uint8_t> HexStringToData(std::string hex);
 -	std::string DataToHexString(std::vector<uint8_t>);
 -
 -	std::string ToxAddressToId(std::string);
  	static bool IsFileExists(std::tstring path);
  };
 diff --git a/protocols/Tox/src/tox_search.cpp b/protocols/Tox/src/tox_search.cpp index 8e1df68786..d62eccd593 100644 --- a/protocols/Tox/src/tox_search.cpp +++ b/protocols/Tox/src/tox_search.cpp @@ -23,7 +23,7 @@ void CToxProto::SearchByNameAsync(void *arg)  			uint8_t dnsString[256];
  			uint32_t requestId = 0;
 -			int length = tox_generate_dns3_string(dns, dnsString, sizeof(dnsString), &requestId, (uint8_t*)name, strlen(name));
 +			int length = tox_generate_dns3_string(dns, dnsString, sizeof(dnsString), &requestId, (uint8_t*)name, mir_strlen(name));
  			if (length != TOX_ERROR)
  			{
  				dnsString[length] = 0;
 @@ -40,14 +40,14 @@ void CToxProto::SearchByNameAsync(void *arg)  					if (record->wType == DNS_TYPE_TEXT && txt->dwStringCount)
  					{
  						char *recordId = &txt->pStringArray[0][10];
 -						std::vector<uint8_t> address(TOX_FRIEND_ADDRESS_SIZE);
 -						if (tox_decrypt_dns3_TXT(dns, &address[0], (uint8_t*)recordId, strlen(recordId), requestId) != TOX_ERROR)
 +						uint8_t data[TOX_FRIEND_ADDRESS_SIZE];
 +						if (tox_decrypt_dns3_TXT(dns, data, (uint8_t*)recordId, mir_strlen(recordId), requestId) != TOX_ERROR)
  						{
 -							std::string id = DataToHexString(address);
 +							ToxHexAddress address(data, TOX_FRIEND_ADDRESS_SIZE);
  							PROTOSEARCHRESULT psr = { sizeof(PROTOSEARCHRESULT) };
  							psr.flags = PSR_TCHAR;
 -							psr.id = mir_a2t(id.c_str());
 +							psr.id = mir_a2t(address);
  							psr.nick = mir_utf8decodeT(name);
  							TCHAR email[MAX_PATH];
 @@ -115,30 +115,18 @@ HWND __cdecl CToxProto::SearchAdvanced(HWND owner)  	if (std::regex_search(query, match, regex))
  	{
  		std::string address = match[1];
 -		if (IsMe(address))
 -		{
 -			ShowNotification(TranslateT("You cannot add yourself to friend list"), 0);
 -		}
 -		else
 -		{
 -			MCONTACT hContact = FindContact(address);
 -			if (!hContact)
 -			{
 -				PROTOSEARCHRESULT psr = { sizeof(psr) };
 -				psr.flags = PSR_TCHAR;
 -				psr.id = mir_a2t(query.c_str());
 +		MCONTACT hContact = GetContact(address.c_str());
 -				ADDCONTACTSTRUCT acs = { HANDLE_SEARCHRESULT };
 -				acs.szProto = m_szModuleName;
 -				acs.psr = &psr;
 +		PROTOSEARCHRESULT psr = { sizeof(psr) };
 +		psr.flags = PSR_TCHAR;
 +		psr.id = mir_a2t(query.c_str());
 +
 +		ADDCONTACTSTRUCT acs = { HANDLE_SEARCHRESULT };
 +		acs.szProto = m_szModuleName;
 +		acs.psr = &psr;
 +
 +		CallService(MS_ADDCONTACT_SHOW, (WPARAM)owner, (LPARAM)&acs);
 -				CallService(MS_ADDCONTACT_SHOW, (WPARAM)owner, (LPARAM)&acs);
 -			}
 -			else
 -			{
 -				ShowNotification(TranslateT("Contact already in your contact list"), 0, hContact);
 -			}
 -		}
  		ForkThread(&CToxProto::SearchFailedAsync, NULL);
  	}
  	else
 diff --git a/protocols/Tox/src/tox_transfer.cpp b/protocols/Tox/src/tox_transfer.cpp index ce8488438b..a56799f971 100644 --- a/protocols/Tox/src/tox_transfer.cpp +++ b/protocols/Tox/src/tox_transfer.cpp @@ -3,12 +3,11 @@  /* FILE RECEIVING */
  // incoming file flow
 -// send it through miranda
  void CToxProto::OnFriendFile(Tox *tox, int32_t friendNumber, uint8_t fileNumber, uint64_t fileSize, const uint8_t *fileName, uint16_t length, void *arg)
  {
  	CToxProto *proto = (CToxProto*)arg;
 -	MCONTACT hContact = proto->FindContact(friendNumber);
 +	MCONTACT hContact = proto->GetContact(friendNumber);
  	if (hContact)
  	{
  		TCHAR *name = mir_utf8decodeT((char*)fileName);
 @@ -45,7 +44,7 @@ HANDLE __cdecl CToxProto::FileAllow(MCONTACT hContact, HANDLE hTransfer, const P  	// stupid fix
  	TCHAR fullPath[MAX_PATH];
  	mir_sntprintf(fullPath, SIZEOF(fullPath), _T("%s\\%s"), transfer->pfts.tszWorkingDir, transfer->pfts.tszCurrentFile);
 -	transfer->RenameName(fullPath);
 +	transfer->Rename(fullPath);
  	if (!ProtoBroadcastAck(hContact, ACKTYPE_FILE, ACKRESULT_FILERESUME, (HANDLE)transfer, (LPARAM)&transfer->pfts))
  	{
 @@ -73,7 +72,7 @@ int __cdecl CToxProto::FileResume(HANDLE hTransfer, int *action, const PROTOCHAR  	switch (*action)
  	{
  	case FILERESUME_RENAME:
 -		transfer->RenameName(*szFilename);
 +		transfer->Rename(*szFilename);
  		result = transfer->OpenFile(_T("wb"));
  		break;
 @@ -83,7 +82,7 @@ int __cdecl CToxProto::FileResume(HANDLE hTransfer, int *action, const PROTOCHAR  	case FILERESUME_SKIP:
  		result = false;
 -		return 0;
 +		break;
  	case FILERESUME_RESUME:
  		result = transfer->OpenFile(_T("ab"));
 @@ -93,6 +92,7 @@ int __cdecl CToxProto::FileResume(HANDLE hTransfer, int *action, const PROTOCHAR  	if (result)
  	{
  		transfer->Start(tox);
 +		debugLogA("CToxProto::FileResume: start receiving file (%d)", transfer->fileNumber);
  	}
  	else
  	{
 @@ -109,37 +109,40 @@ void CToxProto::OnFileData(Tox *tox, int32_t friendNumber, uint8_t fileNumber, c  {
  	CToxProto *proto = (CToxProto*)arg;
 -	MCONTACT hContact = proto->FindContact(friendNumber);
 -	if (hContact)
 +	MCONTACT hContact = proto->GetContact(friendNumber);
 +	if (hContact == NULL)
  	{
 -		FileTransferParam *transfer = proto->transfers->Get(fileNumber);
 -		if (transfer == NULL)
 -		{
 -			tox_file_send_control(tox, friendNumber, 1, fileNumber, TOX_FILECONTROL_KILL, NULL, 0);
 -			return;
 -		}
 +		proto->debugLogA("CToxProto::OnFileData: cannot find contact by number (%d)", friendNumber);
 +		tox_file_send_control(tox, friendNumber, 1, fileNumber, TOX_FILECONTROL_KILL, NULL, 0);
 +		return;
 +	}
 -		if (fwrite(data, sizeof(uint8_t), size, transfer->hFile) != size)
 -		{
 -			proto->debugLogA("CToxProto::OnFileData: cannot write to file (%d)", fileNumber);
 -			proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0);
 -			transfer->Fail(tox);
 -		}
 +	FileTransferParam *transfer = proto->transfers->Get(fileNumber);
 +	if (transfer == NULL)
 +	{
 +		proto->debugLogA("CToxProto::OnFileData: cannot find transfer by number (%d)", fileNumber);
 +		transfer->Fail(tox);
 +		return;
 +	}
 -		transfer->pfts.totalProgress = transfer->pfts.currentFileProgress += size;
 -		proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)transfer, (LPARAM)&transfer->pfts);
 +	if (fwrite(data, sizeof(uint8_t), size, transfer->hFile) != size)
 +	{
 +		proto->debugLogA("CToxProto::OnFileData: cannot write to file (%d)", fileNumber);
 +		proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0);
 +		transfer->Fail(tox);
 +		return;
  	}
 +
 +	transfer->pfts.totalProgress = transfer->pfts.currentFileProgress += size;
 +	proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)transfer, (LPARAM)&transfer->pfts);
  }
  /* FILE SENDING */
  // outcoming file flow
 -// send request through tox
 -HANDLE __cdecl CToxProto::SendFile(MCONTACT hContact, const PROTOCHAR *szDescription, PROTOCHAR **ppszFiles)
 +HANDLE __cdecl CToxProto::SendFile(MCONTACT hContact, const PROTOCHAR*, PROTOCHAR **ppszFiles)
  {
 -	std::string id = getStringA(hContact, TOX_SETTINGS_ID);
 -	std::vector<uint8_t> clientId = HexStringToData(id);
 -	uint32_t friendNumber = tox_get_friend_number(tox, clientId.data());
 +	uint32_t friendNumber = 0;// getDword(hContact, TOX_SETTINGS_NUMBER, TOX_ERROR);
  	TCHAR *fileName = _tcsrchr(ppszFiles[0], '\\') + 1;
 @@ -148,19 +151,19 @@ HANDLE __cdecl CToxProto::SendFile(MCONTACT hContact, const PROTOCHAR *szDescrip  	_tcsncpy(fileDir, ppszFiles[0], fileDirLength);
  	fileDir[fileDirLength] = '\0';
 -	size_t fileSize = 0;
  	FILE *hFile = _tfopen(ppszFiles[0], _T("rb"));
  	if (hFile == NULL)
  	{
  		debugLogA("CToxProto::SendFilesAsync: cannot open file");
  		return NULL;
  	}
 +
  	fseek(hFile, 0, SEEK_END);
 -	fileSize = ftell(hFile);
 -	fseek(hFile, 0, SEEK_SET);
 +	size_t fileSize = _ftelli64(hFile);
 +	rewind(hFile);
  	char *name = mir_utf8encodeW(fileName);
 -	int fileNumber = tox_new_file_sender(tox, friendNumber, fileSize, (uint8_t*)name, strlen(name));
 +	int fileNumber = tox_new_file_sender(tox, friendNumber, fileSize, (uint8_t*)name, mir_strlen(name));
  	if (fileNumber < 0)
  	{
  		debugLogA("CToxProto::SendFilesAsync: cannot send file");
 @@ -186,51 +189,62 @@ void CToxProto::SendFileAsync(void *arg)  	debugLogA("CToxProto::SendFileAsync: start sending file (%d)", transfer->fileNumber);
  	ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_CONNECTED, (HANDLE)transfer, 0);
 +	size_t dataSize = 0, fileProgress = 0;
  	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);
 -
 -	uint16_t chunkSize = min(fileSize, (size_t)tox_file_data_size(tox, transfer->friendNumber));
 +	size_t chunkSize = min(fileSize, (size_t)tox_file_data_size(tox, transfer->friendNumber));
  	uint8_t *data = (uint8_t*)mir_alloc(chunkSize);
 -	while (transfer->status < FAILED && !feof(transfer->hFile) && fileProgress < fileSize)
 +
 +	while (transfer->status < FAILED && transfer->hFile != NULL && fileProgress < fileSize)
  	{
 -		if (transfer->status == PAUSED)
 +		mir_cslockfull locker(transfer->fileLock);
 +
 +		if (transfer->status == PAUSED || transfer->status == BROKEN)
  		{
 -			Sleep(1000);
 +			if (transfer->status == BROKEN)
 +			{
 +				dataSize = 0;
 +			}
 +			locker.unlock();
 +			Sleep(100);
  			continue;
  		}
 -		//mir_cslock lock(toxLock);
 -
 -		uint16_t size = min(chunkSize, fileSize - fileProgress);
 -		if (fread(data, sizeof(uint8_t), size, transfer->hFile) != size)
 +		if (dataSize == 0)
  		{
 -			transfer->Fail(tox);
 -			debugLogA("CToxProto::SendFileAsync: failed to read from file (%d)", transfer->fileNumber);
 -			ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0);
 -			return;
 +			dataSize = min(chunkSize, fileSize - fileProgress);
 +			if (fread(data, sizeof(uint8_t), dataSize, transfer->hFile) != dataSize)
 +			{
 +				debugLogA("CToxProto::SendFileAsync: failed to read from file (%d)", transfer->fileNumber);
 +				debugLogA("CToxProto::OnFileRequest: failure of sending at %llu of %llu of file (%d)", fileProgress, fileSize, transfer->fileNumber);
 +				ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0);
 +				transfer->Fail(tox);
 +				return;
 +			}
  		}
 -		if (tox_file_send_data(tox, transfer->friendNumber, transfer->fileNumber, data, size) == TOX_ERROR)
 +		if (tox_file_send_data(tox, transfer->friendNumber, transfer->fileNumber, data, dataSize) == TOX_ERROR)
  		{
 -			fseek(transfer->hFile, -size, SEEK_CUR);
 +			//fseek(transfer->hFile, -(long)size, SEEK_CUR);
 +			locker.unlock();
 +			//Sleep(100);
  			continue;
  		}
 -		transfer->pfts.totalProgress = transfer->pfts.currentFileProgress = fileProgress += size;
 +		transfer->pfts.totalProgress = transfer->pfts.currentFileProgress = fileProgress += dataSize;
  		ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DATA, (HANDLE)transfer, (LPARAM)&transfer->pfts);
 +		dataSize = 0;
  	}
 +
  	mir_free(data);
 -	if (transfer->status == STARTED)
 +	if (transfer->status != STARTED)
  	{
 -		//mir_cslock lock(toxLock);
 -		transfer->Finish(tox);
 +		transfer->Fail(tox);
  	}
 +	transfer->Finish(tox);
  }
 -/* GENERAL */
 +/* COMMON */
  // file request is cancelled
  int __cdecl CToxProto::FileCancel(MCONTACT hContact, HANDLE hTransfer)
 @@ -252,12 +266,9 @@ void CToxProto::OnFileRequest(Tox *tox, int32_t friendNumber, uint8_t receive_se  {
  	CToxProto *proto = (CToxProto*)arg;
 -	//mir_cslock lock(proto->toxLock);
 -
 -	MCONTACT hContact = proto->FindContact(friendNumber);
 +	MCONTACT hContact = proto->GetContact(friendNumber);
  	if (hContact)
  	{
 -		
  		FileTransferParam *transfer = proto->transfers->Get(fileNumber);
  		if (transfer == NULL)
  		{
 @@ -268,15 +279,17 @@ void CToxProto::OnFileRequest(Tox *tox, int32_t friendNumber, uint8_t receive_se  		switch (type)
  		{
  		case TOX_FILECONTROL_ACCEPT:
 +			// if friend allow file request
  			if (receive_send == 1)
  			{
 -				// if friend allow file request
  				if (transfer->status == NONE)
  				{
  					proto->ForkThread(&CToxProto::SendFileAsync, transfer);
  				}
  				else
  				{
 +					mir_cslock locker(transfer->fileLock);
 +
  					// unpause file transfer
  					transfer->status = STARTED;
  				}
 @@ -284,24 +297,53 @@ void CToxProto::OnFileRequest(Tox *tox, int32_t friendNumber, uint8_t receive_se  			break;
  		case TOX_FILECONTROL_PAUSE:
 -			transfer->status = PAUSED;
 +			{
 +				mir_cslock locker(transfer->fileLock);
 +
 +				transfer->status = PAUSED;
 +			}
  			break;
  		case TOX_FILECONTROL_RESUME_BROKEN:
 -			// only for sending
 -			if (receive_send == 0)
 +			if (receive_send == 1)
  			{
 +				mir_cslock locker(transfer->fileLock);
 +
 +				// if receiver ask to resume transfer
  				uint64_t progress = *(uint64_t*)data;
 -				transfer->pfts.totalProgress = transfer->pfts.currentFileProgress = progress;
 -				fseek(transfer->hFile, progress, SEEK_SET);
 -				transfer->Start(tox);
 +				if (progress >= transfer->pfts.currentFileSize || length != sizeof(uint64_t))
 +				{
 +					transfer->Fail(tox);
 +				}
 +				if (tox_file_send_control(tox, friendNumber, transfer->GetDirection(), fileNumber, TOX_FILECONTROL_ACCEPT, NULL, 0) == TOX_ERROR)
 +				{
 +					proto->debugLogA("CToxProto::OnFileRequest: failed to resume sending file (%d)",
 +						transfer->pfts.currentFileProgress, transfer->pfts.currentFileSize, transfer->fileNumber);
 +					proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_FAILED, (HANDLE)transfer, 0);
 +					transfer->Fail(tox);
 +					break;
 +				}
 +				if (transfer->pfts.currentFileProgress != progress)
 +				{
 +					proto->debugLogA("CToxProto::OnFileRequest: change file position from %llu to %llu of file (%d)",
 +						transfer->pfts.currentFileProgress, progress, transfer->fileNumber);
 +					transfer->pfts.totalProgress = transfer->pfts.currentFileProgress = progress;
 +					_fseeki64(transfer->hFile, progress, SEEK_SET);
 +				}
 +				proto->debugLogA("CToxProto::OnFileRequest: resumption of sending at %llu of %llu of file (%d)",
 +					transfer->pfts.currentFileProgress, transfer->pfts.currentFileSize, transfer->fileNumber);
 +				transfer->status = STARTED;
  			}
  			break;
  		case TOX_FILECONTROL_KILL:
 -			transfer->status = CANCELED;
 -			proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)transfer, 0);
 -			proto->transfers->Remove(transfer);
 +			{
 +				mir_cslock locker(transfer->fileLock);
 +
 +				transfer->status = CANCELED;
 +				proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_DENIED, (HANDLE)transfer, 0);
 +				proto->transfers->Remove(transfer);
 +			}
  			break;
  		case TOX_FILECONTROL_FINISHED:
 @@ -314,6 +356,8 @@ void CToxProto::OnFileRequest(Tox *tox, int32_t friendNumber, uint8_t receive_se  			{
  				proto->debugLogA("CToxProto::OnFileRequest: finished sending file (%d)", fileNumber);
  			}
 +			proto->debugLogA("CToxProto::OnFileRequest: %llu of %llu of file(%d) was transferred successfully",
 +				transfer->pfts.currentFileProgress, transfer->pfts.currentFileSize, transfer->fileNumber);
  			proto->ProtoBroadcastAck(transfer->pfts.hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, (HANDLE)transfer, 0);
  			proto->transfers->Remove(transfer);
  			break;
 diff --git a/protocols/Tox/src/tox_transfer.h b/protocols/Tox/src/tox_transfer.h index f0732ca3b0..7cbbffe3ee 100644 --- a/protocols/Tox/src/tox_transfer.h +++ b/protocols/Tox/src/tox_transfer.h @@ -6,6 +6,7 @@ enum FILE_TRANSFER_STATUS  	NONE,
  	STARTED,
  	PAUSED,
 +	BROKEN,
  	FAILED,
  	CANCELED,
  	FINISHED,
 @@ -17,6 +18,7 @@ struct FileTransferParam  	PROTOFILETRANSFERSTATUS pfts;
  	FILE_TRANSFER_STATUS status;
  	FILE *hFile;
 +	mir_cs fileLock;
  	int friendNumber;
  	int fileNumber;
 @@ -45,37 +47,37 @@ struct FileTransferParam  		return hFile != NULL;
  	}
 -	void Start(Tox *tox)
 +	int Start(Tox *tox)
  	{
  		status = STARTED;
 -		tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_ACCEPT, NULL, 0);
 +		return tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_ACCEPT, NULL, 0);
  	}
 -	void Resume(Tox *tox)
 +	int Resume(Tox *tox)
  	{
  		status = STARTED;
 -		tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_RESUME_BROKEN, (uint8_t*)&pfts.currentFileProgress, sizeof(uint64_t));
 +		return tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_RESUME_BROKEN, (uint8_t*)&pfts.currentFileProgress, sizeof(pfts.currentFileProgress));
  	}
 -	void Fail(Tox *tox)
 +	int Fail(Tox *tox)
  	{
  		status = FAILED;
 -		tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_KILL, NULL, 0);
 +		return tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_KILL, NULL, 0);
  	}
 -	void Cancel(Tox *tox)
 +	int Cancel(Tox *tox)
  	{
  		status = FINISHED;
 -		tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_KILL, NULL, 0);
 +		return tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_KILL, NULL, 0);
  	}
 -	void Finish(Tox *tox)
 +	int Finish(Tox *tox)
  	{
  		status = FINISHED;
 -		tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_FINISHED, NULL, 0);
 +		return tox_file_send_control(tox, friendNumber, GetDirection(), fileNumber, TOX_FILECONTROL_FINISHED, NULL, 0);
  	}
 -	void RenameName(const TCHAR* fileName)
 +	void Rename(const TCHAR* fileName)
  	{
  		pfts.ptszFiles[0] = replaceStrT(pfts.tszCurrentFile, fileName);
  	}
 @@ -94,9 +96,10 @@ struct FileTransferParam  		}
  		mir_free(pfts.pszFiles[0]);
  		mir_free(pfts.pszFiles);
 -		if (hFile)
 +		if (hFile != NULL)
  		{
  			fclose(hFile);
 +			hFile = NULL;
  		}
  	}
  };
 @@ -107,7 +110,7 @@ private:  	std::map<uint8_t, FileTransferParam*> transfers;
  public:
 -	int Count() const
 +	size_t Count() const
  	{
  		return transfers.size();
  	}
 @@ -120,7 +123,7 @@ public:  		}
  	}
 -	FileTransferParam * Get(uint8_t fileNumber)
 +	FileTransferParam* Get(uint8_t fileNumber)
  	{
  		if (transfers.find(fileNumber) != transfers.end())
  		{
 @@ -129,9 +132,9 @@ public:  		return NULL;
  	}
 -	FileTransferParam * At(int index)
 +	FileTransferParam* GetAt(size_t index)
  	{
 -		if (Count() < index)
 +		if (index < Count())
  		{
  			std::map<uint8_t, FileTransferParam*>::iterator it = transfers.begin();
  			std::advance(it, index);
 diff --git a/protocols/Tox/src/tox_utils.cpp b/protocols/Tox/src/tox_utils.cpp index e3bf7d9707..14caa84026 100644 --- a/protocols/Tox/src/tox_utils.cpp +++ b/protocols/Tox/src/tox_utils.cpp @@ -73,43 +73,6 @@ MEVENT CToxProto::AddDbEvent(MCONTACT hContact, WORD type, DWORD timestamp, DWOR  	return db_event_add(hContact, &dbei);
  }
 -std::vector<uint8_t> CToxProto::HexStringToData(std::string hex)
 -{
 -	std::stringstream ss;
 -	std::vector<uint8_t> data;
 -
 -	size_t count = hex.length() / 2;
 -	for (size_t i = 0; i < count; i++)
 -	{
 -		unsigned byte;
 -		std::istringstream hex_byte(hex.substr(i * 2, 2));
 -		hex_byte >> std::hex >> byte;
 -		data.push_back(static_cast<unsigned char>(byte));
 -	}
 -
 -	return data;
 -}
 -
 -std::string CToxProto::DataToHexString(std::vector<uint8_t> data)
 -{
 -	std::ostringstream oss;
 -	oss << std::hex << std::uppercase << std::setfill('0');
 -	for (size_t i = 0; i < data.size(); i++)
 -	{
 -		oss << std::setw(2) << static_cast<int>(data[i]);
 -	}
 -	return oss.str();
 -}
 -
 -std::string  CToxProto::ToxAddressToId(std::string address)
 -{
 -	if (address.length() > TOX_CLIENT_ID_SIZE * 2)
 -	{
 -		address.erase(address.begin() + TOX_CLIENT_ID_SIZE * 2, address.end());
 -	}
 -	return address;
 -}
 -
  bool CToxProto::IsFileExists(std::tstring path)
  {
  	//return ::GetFileAttributes(fileName) != DWORD(-1)
  | 
