From 32b48e3baea25d01efde34843978cb3b94507372 Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Fri, 26 Sep 2014 22:41:54 +0000 Subject: Tox: - updater tox core - avatars support part 2 git-svn-id: http://svn.miranda-ng.org/main/trunk@10609 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Tox/src/tox_account.cpp | 8 +- protocols/Tox/src/tox_avatars.cpp | 171 ++++++++++++++++++++------------------ protocols/Tox/src/tox_proto.cpp | 6 +- protocols/Tox/src/tox_proto.h | 1 + 4 files changed, 101 insertions(+), 85 deletions(-) (limited to 'protocols/Tox/src') diff --git a/protocols/Tox/src/tox_account.cpp b/protocols/Tox/src/tox_account.cpp index 8af024e9f8..b7c7276c12 100644 --- a/protocols/Tox/src/tox_account.cpp +++ b/protocols/Tox/src/tox_account.cpp @@ -55,7 +55,7 @@ void CToxProto::InitToxCore() tox_callback_file_control(tox, OnFileRequest, this); tox_callback_file_send_request(tox, OnFriendFile, this); tox_callback_file_data(tox, OnFileData, this); - // avatars + // avatars tox_callback_avatar_info(tox, OnGotFriendAvatarInfo, this); tox_callback_avatar_data(tox, OnGotFriendAvatarData, this); @@ -71,6 +71,12 @@ void CToxProto::InitToxCore() tox_get_address(tox, &pubKey[0]); std::string address = DataToHexString(pubKey); setString(NULL, TOX_SETTINGS_ID, address.c_str()); + + std::tstring avatarPath = GetContactAvatarFilePath(NULL); + if (IsFileExists(avatarPath)) + { + SetToxAvatar(avatarPath); + } } void CToxProto::UninitToxCore() diff --git a/protocols/Tox/src/tox_avatars.cpp b/protocols/Tox/src/tox_avatars.cpp index eab33d205c..820ad0cc2f 100644 --- a/protocols/Tox/src/tox_avatars.cpp +++ b/protocols/Tox/src/tox_avatars.cpp @@ -9,7 +9,7 @@ TCHAR* CToxProto::GetContactAvatarFilePath(MCONTACT hContact) if (dwAttributes == 0xffffffff || (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) CallService(MS_UTILS_CREATEDIRTREET, 0, (LPARAM)path); - ptrA id(getStringA(hContact, TOX_SETTINGS_ID)); + ptrT id(getTStringA(hContact, TOX_SETTINGS_ID)); if (hContact != NULL) mir_sntprintf(path, MAX_PATH, _T("%s\\%s.jpg"), path, id); else if (id != NULL) @@ -20,6 +20,68 @@ TCHAR* CToxProto::GetContactAvatarFilePath(MCONTACT hContact) return mir_tstrdup(path); } +bool CToxProto::SetToxAvatar(std::tstring path, bool checkHash) +{ + int length; + uint8_t *data; + FILE *hFile = _tfopen(path.c_str(), L"rb"); + if (!hFile) + { + debugLogA("CToxProto::SetMyAvatar: failed to open avatar file"); + return false; + } + + fseek(hFile, 0, SEEK_END); + length = ftell(hFile); + rewind(hFile); + if (length > TOX_AVATAR_MAX_DATA_LENGTH) + { + fclose(hFile); + debugLogA("CToxProto::SetMyAvatar: new avatar size is excessive"); + return false; + } + + data = (uint8_t*)mir_alloc(length); + size_t readed = fread(data, sizeof(uint8_t), length, hFile); + if (readed != length) + { + fclose(hFile); + debugLogA("CToxProto::SetMyAvatar: failed to read avatar file"); + return false; + } + fclose(hFile); + + DBVARIANT dbv; + uint8_t hash[TOX_HASH_LENGTH]; + tox_hash(hash, data, TOX_HASH_LENGTH); + if (checkHash && !db_get(NULL, m_szModuleName, TOX_SETTINGS_AVATAR_HASH, &dbv)) + { + if (memcmp(hash, dbv.pbVal, TOX_HASH_LENGTH) == 0) + { + db_free(&dbv); + mir_free(data); + debugLogA("CToxProto::SetMyAvatar: new avatar is same with old"); + return false; + } + db_free(&dbv); + } + + if (tox_set_avatar(tox, TOX_AVATAR_FORMAT_PNG, data, length) == TOX_ERROR) + { + mir_free(data); + debugLogA("CToxProto::SetMyAvatar: failed to set new avatar"); + return false; + } + mir_free(data); + + if (checkHash) + { + db_set_blob(NULL, m_szModuleName, TOX_SETTINGS_AVATAR_HASH, (void*)hash, TOX_HASH_LENGTH); + } + + return true; +} + INT_PTR CToxProto::GetAvatarCaps(WPARAM wParam, LPARAM lParam) { switch (wParam) @@ -29,35 +91,20 @@ INT_PTR CToxProto::GetAvatarCaps(WPARAM wParam, LPARAM lParam) POINT *size = (POINT *)lParam; if (size) { - size->x = -1; - size->y = -1; + size->x = 300; + size->y = 300; } } break; - case AF_PROPORTION: - return PIP_NONE; - - case AF_FORMATSUPPORTED: - return lParam == PA_FORMAT_PNG; - case AF_ENABLED: return 1; - case AF_DONTNEEDDELAYS: - return 1; + case AF_FORMATSUPPORTED: + return lParam == PA_FORMAT_PNG; case AF_MAXFILESIZE: - return TOX_MAX_AVATAR_DATA_LENGTH; - - case AF_DELAYAFTERFAIL: - // do not request avatar again if server gave an error - return 1;// * 60 * 60 * 1000; // one hour - - case AF_FETCHIFPROTONOTVISIBLE: - case AF_FETCHIFCONTACTOFFLINE: - // avatars can be fetched all the time (server only operation) - return 1; + return TOX_AVATAR_MAX_DATA_LENGTH; } return 0; @@ -70,10 +117,10 @@ INT_PTR CToxProto::GetAvatarInfo(WPARAM, LPARAM lParam) ptrA id(getStringA(pai->hContact, TOX_SETTINGS_ID)); if (id != NULL) { - ptrT path(GetContactAvatarFilePath(pai->hContact)); - if (path && !_waccess(path, 0)) + std::tstring path = GetContactAvatarFilePath(pai->hContact); + if (IsFileExists(path)) { - _tcsncpy(pai->filename, path, SIZEOF(pai->filename)); + _tcsncpy(pai->filename, path.c_str(), SIZEOF(pai->filename)); pai->format = PA_FORMAT_PNG; return GAIR_SUCCESS; @@ -104,72 +151,31 @@ INT_PTR CToxProto::GetMyAvatar(WPARAM wParam, LPARAM lParam) INT_PTR CToxProto::SetMyAvatar(WPARAM wParam, LPARAM lParam) { TCHAR *path = (TCHAR*)lParam; + std::tstring avatarPath = GetContactAvatarFilePath(NULL); if (path != NULL) { - ptrT avatarPath(GetContactAvatarFilePath(NULL)); - if (!_tcscmp(path, avatarPath)) - { - debugLogA("CToxProto::SetMyAvatar: new avatar path are same with old"); - return -1; - } - - if (!CopyFile(path, avatarPath, FALSE)) - { - debugLogA("CToxProto::SetMyAvatar: failed to copy new avatar to local storage"); - return -1; - } - - int length; - uint8_t *data; - FILE *hFile = _tfopen(avatarPath, L"rb"); - if (!hFile) - { - debugLogA("CToxProto::SetMyAvatar: failed to open avatar file"); - return -1; - } - - fseek(hFile, 0, SEEK_END); - length = ftell(hFile); - fseek(hFile, 0, SEEK_SET); - if (length > TOX_MAX_AVATAR_DATA_LENGTH) + if (!CopyFile(path, avatarPath.c_str(), FALSE)) { - fclose(hFile); - debugLogA("CToxProto::SetMyAvatar: new avatar size is excessive"); + debugLogA("CToxProto::SetMyAvatar: failed to copy new avatar to avatar cache"); return -1; } - data = new uint8_t[length + 1]; - if (fread(data, length, 1, hFile) != length) + SetToxAvatar(avatarPath, true); + } + else + { + if (tox_set_avatar(tox, TOX_AVATAR_FORMAT_NONE, NULL, 0) == TOX_ERROR) { - fclose(hFile); - debugLogA("CToxProto::SetMyAvatar: failed to read avatar file"); + debugLogA("CToxProto::SetMyAvatar: failed to unset avatar"); return -1; } - fclose(hFile); - DBVARIANT dbv; - uint8_t hash[TOX_AVATAR_HASH_LENGTH]; - tox_avatar_hash(tox, &hash[0], data, length); - if (!db_get(NULL, m_szModuleName, TOX_SETTINGS_AVATAR_HASH, &dbv)) + if (IsFileExists(avatarPath)) { - if (memcmp(hash, dbv.pbVal, TOX_AVATAR_HASH_LENGTH) == 0) - { - db_free(&dbv); - delete data; - debugLogW(L"CToxProto::SetMyAvatar: new avatar is same with old"); - return -1; - } - db_free(&dbv); + DeleteFile(avatarPath.c_str()); } - if (tox_set_avatar(tox, TOX_AVATARFORMAT_PNG, data, length) == TOX_ERROR) - { - delete data; - debugLogA("CToxProto::SetMyAvatar: failed to set new avatar"); - return -1; - } - - delete data; + db_unset(NULL, m_szModuleName, TOX_SETTINGS_AVATAR_HASH); } return 0; @@ -183,17 +189,20 @@ void CToxProto::OnGotFriendAvatarInfo(Tox *tox, int32_t number, uint8_t format, if (hContact) { TCHAR *path = proto->GetContactAvatarFilePath(hContact); - if (format == TOX_AVATARFORMAT_NONE) + if (format == TOX_AVATAR_FORMAT_NONE) { proto->delSetting(hContact, TOX_SETTINGS_AVATAR_HASH); - DeleteFile(path); + if (IsFileExists(path)) + { + DeleteFile(path); + } } else { DBVARIANT dbv; if (!db_get(hContact, proto->m_szModuleName, TOX_SETTINGS_AVATAR_HASH, &dbv)) { - if (memcmp(hash, dbv.pbVal, TOX_AVATAR_HASH_LENGTH) != 0) + if (memcmp(hash, dbv.pbVal, TOX_HASH_LENGTH) != 0) { tox_request_avatar_data(proto->tox, number); } @@ -210,7 +219,7 @@ void CToxProto::OnGotFriendAvatarData(Tox *tox, int32_t number, uint8_t format, MCONTACT hContact = proto->FindContact(number); if (hContact) { - db_set_blob(hContact, proto->m_szModuleName, TOX_SETTINGS_AVATAR_HASH, hash, TOX_AVATAR_HASH_LENGTH); + db_set_blob(hContact, proto->m_szModuleName, TOX_SETTINGS_AVATAR_HASH, hash, TOX_HASH_LENGTH); TCHAR *path = proto->GetContactAvatarFilePath(hContact); FILE *hFile = _tfopen(path, L"wb"); diff --git a/protocols/Tox/src/tox_proto.cpp b/protocols/Tox/src/tox_proto.cpp index 19d830d97b..3016a400ee 100644 --- a/protocols/Tox/src/tox_proto.cpp +++ b/protocols/Tox/src/tox_proto.cpp @@ -41,10 +41,10 @@ PROTO(protoName, userName) CallService(MS_DB_EVENT_REGISTERTYPE, 0, (LPARAM)&dbEventType); // avatars - /*CreateProtoService(PS_GETAVATARCAPS, &CToxProto::GetAvatarCaps); + CreateProtoService(PS_GETAVATARCAPS, &CToxProto::GetAvatarCaps); CreateProtoService(PS_GETAVATARINFOT, &CToxProto::GetAvatarInfo); CreateProtoService(PS_GETMYAVATART, &CToxProto::GetMyAvatar); - CreateProtoService(PS_SETMYAVATART, &CToxProto::SetMyAvatar);*/ + CreateProtoService(PS_SETMYAVATART, &CToxProto::SetMyAvatar); } CToxProto::~CToxProto() @@ -63,7 +63,7 @@ DWORD_PTR __cdecl CToxProto::GetCaps(int type, MCONTACT hContact) case PFLAGNUM_2: return PF2_ONLINE | PF2_SHORTAWAY | PF2_LIGHTDND; case PFLAGNUM_4: - return PF4_IMSENDUTF | PF4_SINGLEFILEONLY | PF4_NOAUTHDENYREASON |PF4_FORCEAUTH + return PF4_IMSENDUTF | PF4_SINGLEFILEONLY | PF4_NOAUTHDENYREASON | PF4_FORCEAUTH | PF4_FORCEADDED | PF4_SUPPORTTYPING | PF4_AVATARS; case PFLAG_UNIQUEIDTEXT: return (INT_PTR)"Tox ID"; diff --git a/protocols/Tox/src/tox_proto.h b/protocols/Tox/src/tox_proto.h index b0cda8f390..06b15d3197 100644 --- a/protocols/Tox/src/tox_proto.h +++ b/protocols/Tox/src/tox_proto.h @@ -199,6 +199,7 @@ private: // avatars TCHAR* GetContactAvatarFilePath(MCONTACT hContact); + bool SetToxAvatar(std::tstring path, bool checkHash = false); INT_PTR __cdecl GetAvatarCaps(WPARAM wParam, LPARAM lParam); INT_PTR __cdecl GetAvatarInfo(WPARAM, LPARAM lParam); -- cgit v1.2.3