/* Copyright (c) 2015 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 "stdafx.h" INT_PTR CSkypeProto::SvcGetAvatarCaps(WPARAM wParam, LPARAM lParam) { switch (wParam) { case AF_MAXSIZE: ((POINT*)lParam)->x = 150; ((POINT*)lParam)->y = 150; return 0; case AF_MAXFILESIZE: return 32000; case AF_PROPORTION: return PIP_SQUARE; case AF_FORMATSUPPORTED: case AF_ENABLED: case AF_DONTNEEDDELAYS: case AF_FETCHIFPROTONOTVISIBLE: case AF_FETCHIFCONTACTOFFLINE: return 1; } return 0; } void CSkypeProto::ReloadAvatarInfo(MCONTACT hContact) { if (hContact == NULL) { CallService(MS_AV_REPORTMYAVATARCHANGED, (WPARAM)m_szModuleName, 0); return; } PROTO_AVATAR_INFORMATION ai = { 0 }; ai.hContact = hContact; SvcGetAvatarInfo(0, (LPARAM)&ai); } void CSkypeProto::OnReceiveAvatar(const NETLIBHTTPREQUEST *response, void *arg) { if (response == NULL || response->pData == NULL) return; MCONTACT hContact = (MCONTACT)arg; if (response->resultCode != 200) return; PROTO_AVATAR_INFORMATION ai = { 0 }; ai.format = ProtoGetBufferFormat(response->pData); setByte(hContact, "AvatarType", ai.format); GetAvatarFileName(hContact, ai.filename, _countof(ai.filename)); FILE *out = _tfopen(ai.filename, _T("wb")); if (out == NULL) { ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, &ai, 0); return; } fwrite(response->pData, 1, response->dataLength, out); fclose(out); setByte(hContact, "NeedNewAvatar", 0); ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, &ai, 0); } void CSkypeProto::OnSentAvatar(const NETLIBHTTPREQUEST *response) { if (response == NULL) return; JSONNode root = JSONNode::parse(response->pData); if (!root) return; } INT_PTR CSkypeProto::SvcGetAvatarInfo(WPARAM, LPARAM lParam) { PROTO_AVATAR_INFORMATION *pai = (PROTO_AVATAR_INFORMATION*)lParam; ptrA szUrl(getStringA(pai->hContact, "AvatarUrl")); if (szUrl == NULL) return GAIR_NOAVATAR; pai->format = getByte(pai->hContact, "AvatarType", PA_FORMAT_JPEG); TCHAR tszFileName[MAX_PATH]; GetAvatarFileName(pai->hContact, tszFileName, _countof(tszFileName)); _tcsncpy(pai->filename, tszFileName, _countof(pai->filename)); if (::_taccess(pai->filename, 0) == 0 && !getBool(pai->hContact, "NeedNewAvatar", 0)) return GAIR_SUCCESS; if (IsOnline()) { PushRequest(new GetAvatarRequest(szUrl), &CSkypeProto::OnReceiveAvatar, (void*)pai->hContact); debugLogA("Requested to read an avatar from '%s'", szUrl); return GAIR_WAITFOR; } debugLogA("No avatar"); return GAIR_NOAVATAR; } INT_PTR CSkypeProto::SvcGetMyAvatar(WPARAM wParam, LPARAM lParam) { TCHAR path[MAX_PATH]; GetAvatarFileName(NULL, path, _countof(path)); _tcsncpy((TCHAR*)wParam, path, (int)lParam); return 0; } void CSkypeProto::GetAvatarFileName(MCONTACT hContact, TCHAR* pszDest, size_t cbLen) { int tPathLen = mir_sntprintf(pszDest, cbLen, _T("%s\\%s"), VARST(_T("%miranda_avatarcache%")), m_tszUserName); DWORD dwAttributes = GetFileAttributes(pszDest); if (dwAttributes == 0xffffffff || (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) CreateDirectoryTreeT(pszDest); pszDest[tPathLen++] = '\\'; const TCHAR* szFileType = ProtoGetAvatarExtension(getByte(hContact, "AvatarType", PA_FORMAT_JPEG)); CMStringA username(ptrA(getStringA(hContact, SKYPE_SETTINGS_ID))); username.Replace("live:", "__live_"); username.Replace("facebook:", "__facebook_"); mir_sntprintf(pszDest + tPathLen, MAX_PATH - tPathLen, _T("%S%s"), username.c_str(), szFileType); } void CSkypeProto::SetAvatarUrl(MCONTACT hContact, CMString &tszUrl) { ptrT oldUrl(getTStringA(hContact, "AvatarUrl")); if (oldUrl != NULL) if (tszUrl == oldUrl) return; if (tszUrl.IsEmpty()) { delSetting(hContact, "AvatarUrl"); ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, NULL, 0); } else { setTString(hContact, "AvatarUrl", tszUrl.GetBuffer()); setByte(hContact, "NeedNewAvatar", 1); PROTO_AVATAR_INFORMATION ai = { 0 }; ai.hContact = hContact; GetAvatarFileName(ai.hContact, ai.filename, _countof(ai.filename)); ai.format = ProtoGetAvatarFormat(ai.filename); ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, (HANDLE)&ai, 0); } } INT_PTR CSkypeProto::SvcSetMyAvatar(WPARAM, LPARAM lParam) { TCHAR *path = (TCHAR*)lParam; TCHAR avatarPath[MAX_PATH]; GetAvatarFileName(NULL, avatarPath, _countof(avatarPath)); if (path != NULL) { if (!CopyFile(path, avatarPath, FALSE)) { debugLogA("CSkypeProto::SetMyAvatar: failed to copy new avatar to avatar cache"); return -1; } FILE *hFile = _tfopen(path, L"rb"); if (!hFile) { debugLogA("CSkypeProto::SetMyAvatar: failed to open avatar file"); return -1; } fseek(hFile, 0, SEEK_END); size_t length = ftell(hFile); if (length == -1) { debugLogA("CSkypeProto::SvcSetMyAvatar: failed to get avatar file size"); fclose(hFile); return -1; } rewind(hFile); ptrA data((char*)mir_alloc(length)); if (data == NULL || fread(data, sizeof(char), length, hFile) != length) { debugLogA("CSkypeProto::SvcSetMyAvatar: failed to read avatar file"); fclose(hFile); return -1; } fclose(hFile); PushRequest(new SetAvatarRequest(data, length, li), &CSkypeProto::OnSentAvatar); } else { if (IsFileExists(avatarPath)) { DeleteFile(avatarPath); } } return 0; }