diff options
author | George Hazan <george.hazan@gmail.com> | 2013-01-29 20:15:01 +0000 |
---|---|---|
committer | George Hazan <george.hazan@gmail.com> | 2013-01-29 20:15:01 +0000 |
commit | 43eecbf2a0d8dc84dc6f41cb2ef5e1609418a35a (patch) | |
tree | d76ccadccec7b21a43da8600b177b565b7f1030c | |
parent | 82b32bb1d683867729cd4fb259d9d1edc3b0039e (diff) |
MSN HTTP avatars, part III, final
fixes #204
git-svn-id: http://svn.miranda-ng.org/main/trunk@3345 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
-rw-r--r-- | protocols/MSN/src/msn_avatar.cpp | 80 | ||||
-rw-r--r-- | protocols/MSN/src/msn_proto.cpp | 2 | ||||
-rw-r--r-- | protocols/MSN/src/msn_proto.h | 90 | ||||
-rw-r--r-- | protocols/MSN/src/msn_threads.cpp | 30 |
4 files changed, 129 insertions, 73 deletions
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 <http://www.gnu.org/licenses/>. 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<MsgQueueEntry> lsMessageQueue;
CRITICAL_SECTION csAvatarQueue;
- OBJLIST<AvatarQueueEntry> lsAvatarQueue;
+ LIST<AvatarQueueEntry> 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);
|