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 +++++++++++++++++++++++++++++++++- protocols/MSN/src/msn_proto.cpp | 2 +- protocols/MSN/src/msn_proto.h | 90 +++++++++++++++++++++------------------ protocols/MSN/src/msn_threads.cpp | 30 ------------- 4 files changed, 129 insertions(+), 73 deletions(-) (limited to 'protocols') 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; } } diff --git a/protocols/MSN/src/msn_proto.cpp b/protocols/MSN/src/msn_proto.cpp index cf7db58876..b9f4174a55 100644 --- a/protocols/MSN/src/msn_proto.cpp +++ b/protocols/MSN/src/msn_proto.cpp @@ -233,7 +233,7 @@ int CMsnProto::OnModulesLoaded(WPARAM, LPARAM) int CMsnProto::OnPreShutdown(WPARAM, LPARAM) { -// MSN_CloseThreads(); + SetEvent(hevAvatarQueue); return 0; } diff --git a/protocols/MSN/src/msn_proto.h b/protocols/MSN/src/msn_proto.h index 757b7b55c0..87f343c7a7 100644 --- a/protocols/MSN/src/msn_proto.h +++ b/protocols/MSN/src/msn_proto.h @@ -149,7 +149,8 @@ struct CMsnProto : public PROTO_INTERFACE, public MZeroedObject OBJLIST lsMessageQueue; CRITICAL_SECTION csAvatarQueue; - OBJLIST lsAvatarQueue; + LIST lsAvatarQueue; + HANDLE hevAvatarQueue; LONG sttChatID; @@ -167,18 +168,18 @@ struct CMsnProto : public PROTO_INTERFACE, public MZeroedObject bool usingGateway; char* msnExternalIP; - char* msnPreviousUUX; - char* msnLastStatusMsg; + char* msnPreviousUUX; + char* msnLastStatusMsg; - char* mailsoundname; - char* alertsoundname; + char* mailsoundname; + char* alertsoundname; - unsigned langpref; + unsigned langpref; unsigned emailEnabled; unsigned abchMigrated; unsigned myFlags; - unsigned msnOtherContactsBlocked; + unsigned msnOtherContactsBlocked; int mUnreadMessages; int mUnreadJunkEmails; clock_t mHttpsTS; @@ -192,9 +193,9 @@ struct CMsnProto : public PROTO_INTERFACE, public MZeroedObject HANDLE hMSNAvatarsFolder; HANDLE hCustomSmileyFolder; - bool InitCstFldRan; - bool isConnectSuccess; - bool isIdle; + bool InitCstFldRan; + bool isConnectSuccess; + bool isIdle; void InitCustomFolders(void); @@ -203,47 +204,41 @@ struct CMsnProto : public PROTO_INTERFACE, public MZeroedObject char* getSslResult(char** parUrl, const char* parAuthInfo, const char* hdrs, unsigned& status); bool getMyAvatarFile(char *url, TCHAR *fname); - void AvatarQueue_Init(void); - void AvatarQueue_Uninit(void); - void MSN_GoOffline(void); - void MSN_GetAvatarFileName(HANDLE hContact, TCHAR* pszDest, size_t cbLen, const TCHAR *ext); - void pushAvatarRequest(HANDLE hContact, LPCSTR pszUrl); - int MSN_SetMyAvatar(const TCHAR* szFname, void* pData, size_t cbLen); void MSN_GetCustomSmileyFileName(HANDLE hContact, TCHAR* pszDest, size_t cbLen, const char* SmileyName, int Type); const char* MirandaStatusToMSN(int status); - WORD MSNStatusToMiranda(const char *status); + WORD MSNStatusToMiranda(const char *status); char** GetStatusMsgLoc(int status); void MSN_SendStatusMessage(const char* msg); void MSN_SetServerStatus(int newStatus); - void MSN_StartStopTyping(ThreadData* info, bool start); - void MSN_SendTyping(ThreadData* info, const char* email, int netId ); + void MSN_StartStopTyping(ThreadData* info, bool start); + void MSN_SendTyping(ThreadData* info, const char* email, int netId ); - void MSN_InitSB(ThreadData* info, const char* szEmail); - void MSN_ReceiveMessage(ThreadData* info, char* cmdString, char* params); + void MSN_InitSB(ThreadData* info, const char* szEmail); + void MSN_ReceiveMessage(ThreadData* info, char* cmdString, char* params); int MSN_HandleCommands(ThreadData* info, char* cmdString); int MSN_HandleErrors(ThreadData* info, char* cmdString); - void sttProcessNotificationMessage(char* buf, unsigned len); - void sttProcessStatusMessage(char* buf, unsigned len, const char* wlid); - void sttProcessPage(char* buf, unsigned len); - void sttProcessRemove(char* buf, size_t len); - void sttProcessAdd(char* buf, size_t len); - void sttProcessYFind(char* buf, size_t len); - void sttCustomSmiley(const char* msgBody, char* email, char* nick, int iSmileyType); - void sttInviteMessage(ThreadData* info, char* msgBody, char* email, char* nick); - void sttSetMirVer(HANDLE hContact, DWORD dwValue, bool always); + void sttProcessNotificationMessage(char* buf, unsigned len); + void sttProcessStatusMessage(char* buf, unsigned len, const char* wlid); + void sttProcessPage(char* buf, unsigned len); + void sttProcessRemove(char* buf, size_t len); + void sttProcessAdd(char* buf, size_t len); + void sttProcessYFind(char* buf, size_t len); + void sttCustomSmiley(const char* msgBody, char* email, char* nick, int iSmileyType); + void sttInviteMessage(ThreadData* info, char* msgBody, char* email, char* nick); + void sttSetMirVer(HANDLE hContact, DWORD dwValue, bool always); void LoadOptions(void); - void InitPopups(void); - void MSN_ShowPopup(const TCHAR* nickname, const TCHAR* msg, int flags, const char* url, HANDLE hContact = NULL); - void MSN_ShowPopup(const HANDLE hContact, const TCHAR* msg, int flags); - void MSN_ShowError(const char* msgtext, ...); + void InitPopups(void); + void MSN_ShowPopup(const TCHAR* nickname, const TCHAR* msg, int flags, const char* url, HANDLE hContact = NULL); + void MSN_ShowPopup(const HANDLE hContact, const TCHAR* msg, int flags); + void MSN_ShowError(const char* msgtext, ...); - void MSN_SetNicknameUtf(const char* nickname); - void MSN_SendNicknameUtf(const char* nickname); + void MSN_SetNicknameUtf(const char* nickname); + void MSN_SendNicknameUtf(const char* nickname); typedef struct { TCHAR *szName; const char *szMimeType; unsigned char *data; size_t dataSize; } StoreAvatarData; void __cdecl msn_storeAvatarThread(void* arg); @@ -303,7 +298,6 @@ struct CMsnProto : public PROTO_INTERFACE, public MZeroedObject void Threads_Uninit(void); void MSN_CloseConnections(void); - void MSN_CloseThreads(void); void MSN_InitThreads(void); int MSN_GetChatThreads(ThreadData** parResult); int MSN_GetActiveThreads(ThreadData**); @@ -490,10 +484,24 @@ struct CMsnProto : public PROTO_INTERFACE, public MZeroedObject ///////////////////////////////////////////////////////////////////////////////////////// // MSN Authentication - int MSN_GetPassportAuth(void); - char* GenerateLoginBlob(char* challenge); - char* HotmailLogin(const char* url); - void FreeAuthTokens(void); + int MSN_GetPassportAuth(void); + char* GenerateLoginBlob(char* challenge); + char* HotmailLogin(const char* url); + void FreeAuthTokens(void); + + ///////////////////////////////////////////////////////////////////////////////////////// + // MSN avatars support + + void AvatarQueue_Init(void); + void AvatarQueue_Uninit(void); + + void MSN_GetAvatarFileName(HANDLE hContact, TCHAR* pszDest, size_t cbLen, const TCHAR *ext); + int MSN_SetMyAvatar(const TCHAR* szFname, void* pData, size_t cbLen); + + void __cdecl MSN_AvatarsThread(void*); + + void pushAvatarRequest(HANDLE hContact, LPCSTR pszUrl); + bool loadHttpAvatar(AvatarQueueEntry *p); ///////////////////////////////////////////////////////////////////////////////////////// // MSN Mail & Offline messaging support diff --git a/protocols/MSN/src/msn_threads.cpp b/protocols/MSN/src/msn_threads.cpp index ca625b4fa1..25f9a9a765 100644 --- a/protocols/MSN/src/msn_threads.cpp +++ b/protocols/MSN/src/msn_threads.cpp @@ -339,36 +339,6 @@ void CMsnProto::MSN_CloseConnections(void) CallService(MS_NETLIB_SHUTDOWN, (WPARAM)hHttpsConnection, 0); } -void CMsnProto::MSN_CloseThreads(void) -{ - for (unsigned j=6; --j;) - { - EnterCriticalSection(&sttLock); - - bool opcon = false; - for (int i=0; i < sttThreads.getCount(); i++) - opcon |= (sttThreads[i].s != NULL); - - LeaveCriticalSection(&sttLock); - - if (!opcon) break; - - Sleep(250); - } - - EnterCriticalSection(&sttLock); - - for (int i=0; i < sttThreads.getCount(); i++) - { - ThreadData* T = &sttThreads[i]; - - if (T->s != NULL) - CallService(MS_NETLIB_SHUTDOWN, (WPARAM)T->s, 0); - } - - LeaveCriticalSection(&sttLock); -} - void CMsnProto::Threads_Uninit(void) { EnterCriticalSection(&sttLock); -- cgit v1.2.3