From 43eecbf2a0d8dc84dc6f41cb2ef5e1609418a35a Mon Sep 17 00:00:00 2001 From: George Hazan Date: Tue, 29 Jan 2013 20:15:01 +0000 Subject: MSN HTTP avatars, part III, final fixes #204 git-svn-id: http://svn.miranda-ng.org/main/trunk@3345 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/MSN/src/msn_avatar.cpp | 80 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) (limited to 'protocols/MSN/src/msn_avatar.cpp') diff --git a/protocols/MSN/src/msn_avatar.cpp b/protocols/MSN/src/msn_avatar.cpp index b1ed8b1690..bd27529c1f 100644 --- a/protocols/MSN/src/msn_avatar.cpp +++ b/protocols/MSN/src/msn_avatar.cpp @@ -22,11 +22,15 @@ along with this program. If not, see . void CMsnProto::AvatarQueue_Init() { ::InitializeCriticalSection(&csAvatarQueue); + hevAvatarQueue = ::CreateEvent(NULL, FALSE, FALSE, NULL); + + ForkThread(&CMsnProto::MSN_AvatarsThread, 0); } void CMsnProto::AvatarQueue_Uninit() { ::DeleteCriticalSection(&csAvatarQueue); + ::CloseHandle(hevAvatarQueue); } void CMsnProto::pushAvatarRequest(HANDLE hContact, LPCSTR pszUrl) @@ -37,9 +41,83 @@ void CMsnProto::pushAvatarRequest(HANDLE hContact, LPCSTR pszUrl) mir_cslock lck(csAvatarQueue); for (int i=0; i < lsAvatarQueue.getCount(); i++) - if (lsAvatarQueue[i].hContact == hContact) + if (lsAvatarQueue[i]->hContact == hContact) return; lsAvatarQueue.insert(new AvatarQueueEntry(hContact, pszUrl)); + SetEvent(hevAvatarQueue); + } +} + +bool CMsnProto::loadHttpAvatar(AvatarQueueEntry *p) +{ + NETLIBHTTPHEADER nlbhHeaders[1]; + nlbhHeaders[0].szName = "User-Agent"; + nlbhHeaders[0].szValue = (char*)MSN_USER_AGENT; + + NETLIBHTTPREQUEST nlhr = { sizeof(nlhr) }; + nlhr.requestType = REQUEST_GET; + nlhr.flags = NLHRF_HTTP11 | NLHRF_REDIRECT;; + nlhr.szUrl = p->pszUrl; + nlhr.headers = (NETLIBHTTPHEADER*)&nlbhHeaders; + nlhr.headersCount = 1; + + NETLIBHTTPREQUEST *nlhrReply = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)hNetlibUser, (LPARAM)&nlhr); + if (nlhrReply == NULL) + return false; + + if (nlhrReply->resultCode != 200 || nlhrReply->dataLength == 0) { +LBL_Error: + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)nlhrReply); + return false; + } + + const TCHAR *szExt; + int fmt = MSN_GetImageFormat(nlhrReply->pData, &szExt); + if (fmt == PA_FORMAT_UNKNOWN) + goto LBL_Error; + + PROTO_AVATAR_INFORMATIONT AI = { sizeof(AI) }; + AI.format = fmt; + AI.hContact = p->hContact; + MSN_GetAvatarFileName(AI.hContact, AI.filename, SIZEOF(AI.filename), szExt); + _tremove(AI.filename); + + int fileId = _topen(AI.filename, _O_CREAT | _O_TRUNC | _O_WRONLY | O_BINARY, _S_IREAD | _S_IWRITE); + if (fileId == -1) + goto LBL_Error; + + _write(fileId, nlhrReply->pData, (unsigned)nlhrReply->dataLength); + _close(fileId); + + SendBroadcast(p->hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, &AI, 0); + CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)nlhrReply); + return true; +} + +void __cdecl CMsnProto::MSN_AvatarsThread(void*) +{ + while(true) { + if (WaitForSingleObject(hevAvatarQueue, INFINITE) != WAIT_OBJECT_0) + break; + + if ( Miranda_Terminated()) + break; + + AvatarQueueEntry *p = NULL; + { + mir_cslock lck(csAvatarQueue); + if (lsAvatarQueue.getCount() > 0) { + p = lsAvatarQueue[0]; + lsAvatarQueue.remove(0); + } + } + + if (p == NULL) + continue; + + if ( !loadHttpAvatar(p)) + SendBroadcast(p->hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, 0, 0); + delete p; } } -- cgit v1.2.3