From 3507966e548d9590b329499275c9d06b84d167f3 Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Thu, 25 Sep 2014 18:51:10 +0000 Subject: Tox: forgotten file git-svn-id: http://svn.miranda-ng.org/main/trunk@10591 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Tox/src/tox_avatars.cpp | 224 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 protocols/Tox/src/tox_avatars.cpp (limited to 'protocols/Tox') diff --git a/protocols/Tox/src/tox_avatars.cpp b/protocols/Tox/src/tox_avatars.cpp new file mode 100644 index 0000000000..eab33d205c --- /dev/null +++ b/protocols/Tox/src/tox_avatars.cpp @@ -0,0 +1,224 @@ +#include "common.h" + +TCHAR* CToxProto::GetContactAvatarFilePath(MCONTACT hContact) +{ + TCHAR path[MAX_PATH]; + mir_sntprintf(path, SIZEOF(path), _T("%s\\%S"), VARST(_T("%miranda_avatarcache%")), m_szModuleName); + + DWORD dwAttributes = GetFileAttributes(path); + if (dwAttributes == 0xffffffff || (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) + CallService(MS_UTILS_CREATEDIRTREET, 0, (LPARAM)path); + + ptrA id(getStringA(hContact, TOX_SETTINGS_ID)); + if (hContact != NULL) + mir_sntprintf(path, MAX_PATH, _T("%s\\%s.jpg"), path, id); + else if (id != NULL) + mir_sntprintf(path, MAX_PATH, _T("%s\\%s avatar.jpg"), path, id); + else + return NULL; + + return mir_tstrdup(path); +} + +INT_PTR CToxProto::GetAvatarCaps(WPARAM wParam, LPARAM lParam) +{ + switch (wParam) + { + case AF_MAXSIZE: + { + POINT *size = (POINT *)lParam; + if (size) + { + size->x = -1; + size->y = -1; + } + } + 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_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 0; +} + +INT_PTR CToxProto::GetAvatarInfo(WPARAM, LPARAM lParam) +{ + PROTO_AVATAR_INFORMATIONW *pai = (PROTO_AVATAR_INFORMATIONW *)lParam; + + ptrA id(getStringA(pai->hContact, TOX_SETTINGS_ID)); + if (id != NULL) + { + ptrT path(GetContactAvatarFilePath(pai->hContact)); + if (path && !_waccess(path, 0)) + { + _tcsncpy(pai->filename, path, SIZEOF(pai->filename)); + pai->format = PA_FORMAT_PNG; + + return GAIR_SUCCESS; + } + } + + return GAIR_NOAVATAR; +} + +INT_PTR CToxProto::GetMyAvatar(WPARAM wParam, LPARAM lParam) +{ + if (!wParam) + { + return -2; + } + + std::tstring path(GetContactAvatarFilePath(NULL)); + if (IsFileExists(path)) + { + _tcsncpy((TCHAR*)wParam, path.c_str(), (int)lParam); + + return 0; + } + + return -1; +} + +INT_PTR CToxProto::SetMyAvatar(WPARAM wParam, LPARAM lParam) +{ + TCHAR *path = (TCHAR*)lParam; + 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) + { + fclose(hFile); + debugLogA("CToxProto::SetMyAvatar: new avatar size is excessive"); + return -1; + } + + data = new uint8_t[length + 1]; + if (fread(data, length, 1, hFile) != length) + { + fclose(hFile); + debugLogA("CToxProto::SetMyAvatar: failed to read avatar file"); + 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 (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); + } + + 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; + } + + return 0; +} + +void CToxProto::OnGotFriendAvatarInfo(Tox *tox, int32_t number, uint8_t format, uint8_t *hash, void *arg) +{ + CToxProto *proto = (CToxProto*)arg; + + MCONTACT hContact = proto->FindContact(number); + if (hContact) + { + TCHAR *path = proto->GetContactAvatarFilePath(hContact); + if (format == TOX_AVATARFORMAT_NONE) + { + proto->delSetting(hContact, TOX_SETTINGS_AVATAR_HASH); + 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) + { + tox_request_avatar_data(proto->tox, number); + } + db_free(&dbv); + } + } + } +} + +void CToxProto::OnGotFriendAvatarData(Tox *tox, int32_t number, uint8_t format, uint8_t *hash, uint8_t *data, uint32_t length, void *arg) +{ + CToxProto *proto = (CToxProto*)arg; + + MCONTACT hContact = proto->FindContact(number); + if (hContact) + { + db_set_blob(hContact, proto->m_szModuleName, TOX_SETTINGS_AVATAR_HASH, hash, TOX_AVATAR_HASH_LENGTH); + + TCHAR *path = proto->GetContactAvatarFilePath(hContact); + FILE *hFile = _tfopen(path, L"wb"); + if (hFile) + { + fwrite(data, sizeof(uint8_t), length, hFile); + fclose(hFile); + } + mir_free(path); + } +} \ No newline at end of file -- cgit v1.2.3