/* IRC plugin for Miranda IM Copyright (C) 2003 Jörgen Persson 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; either version 2 of the License, or (at your option) any later version. 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, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "irc.h" extern char * IRCPROTONAME; void GetFullAvatarFileName(int dwUin, char* szUid, int dwFormat, char* pszDest, int cbLen) { GetAvatarFileName(dwUin, szUid, pszDest, cbLen); AddAvatarExt(dwFormat, pszDest); } void GetAvatarFileName(int dwUin, char* szUid, char* pszDest, int cbLen) { int tPathLen; CallService(MS_DB_GETPROFILEPATH, cbLen, (LPARAM)pszDest); tPathLen = strlennull(pszDest); tPathLen += null_snprintf(pszDest + tPathLen, MAX_PATH-tPathLen, "\\%s\\", IRCPROTONAME); #ifdef _UNICODE CreateDirectory((LPCWSTR)pszDest, NULL); #else CreateDirectory(pszDest, NULL); #endif if (dwUin != 0) { ltoa(dwUin, pszDest + tPathLen, 10); } else if (szUid) { strcpy(pszDest + tPathLen, szUid); } else { char szBuf[MAX_PATH]; if (CallService(MS_DB_GETPROFILENAME, 250 - tPathLen, (LPARAM)szBuf)) strcpy(pszDest + tPathLen, "avatar" ); else { char* szLastDot = strstr(szBuf, "."); if (szLastDot) while (strstr(szLastDot+1, ".")) szLastDot = strstr(szLastDot+1, "."); if (szLastDot) szLastDot[0] = '\0'; strcpy(pszDest + tPathLen, szBuf); strcat(pszDest + tPathLen, "_avt"); } } } void AddAvatarExt(int dwFormat, char* pszDest) { if (dwFormat == PA_FORMAT_JPEG) strcat(pszDest, ".jpg"); else if (dwFormat == PA_FORMAT_GIF) strcat(pszDest, ".gif"); else if (dwFormat == PA_FORMAT_PNG) strcat(pszDest, ".png"); else if (dwFormat == PA_FORMAT_BMP) strcat(pszDest, ".bmp"); else if (dwFormat == PA_FORMAT_XML) strcat(pszDest, ".xml"); else strcat(pszDest, ".dat"); } int DetectAvatarFormatBuffer(char* pBuffer) { if (!strncmp(pBuffer, "%PNG", 4)) { return PA_FORMAT_PNG; } if (!strncmp(pBuffer, "GIF8", 4)) { return PA_FORMAT_GIF; } if (!strnicmp(pBuffer, "paused) // check if we are ready { icq_packet packet; BYTE nUinLen; DWORD dwCookie; avatarcookie* ack; int i; DWORD dwNow = GetTickCount(); EnterCriticalSection(&cookieMutex); // reused... for(i = 0; i < atsi->runCount;) { // look for timeouted requests if (atsi->runTime[i] < dwNow) { // found outdated, remove atsi->runContact[i] = atsi->runContact[atsi->runCount - 1]; atsi->runTime[i] = atsi->runTime[atsi->runCount - 1]; atsi->runCount--; } else i++; } for(i = 0; i < atsi->runCount; i++) { if (atsi->runContact[i] == hContact) { LeaveCriticalSection(&cookieMutex); NetLog_Server("Ignoring duplicate get %d avatar request.", dwUin); return 0; } } if (atsi->runCount < 4) { // 4 concurent requests at most atsi->runContact[atsi->runCount] = hContact; atsi->runTime[atsi->runCount] = GetTickCount() + 30000; // 30sec to complete request atsi->runCount++; LeaveCriticalSection(&cookieMutex); nUinLen = getUIDLen(dwUin, szUid); ack = (avatarcookie*)SAFE_MALLOC(sizeof(avatarcookie)); if (!ack) return 0; // out of memory, go away ack->dwUin = 1; //dwUin; // I should be damned for this - only to identify get request ack->hContact = hContact; ack->hash = (char*)SAFE_MALLOC(hashlen); memcpy(ack->hash, hash, hashlen); // copy the data ack->hashlen = hashlen; ack->szFile = null_strdup(file); // we duplicate the string dwCookie = AllocateCookie(CKT_AVATAR, ICQ_AVATAR_GET_REQUEST, dwUin, ack); serverPacketInit(&packet, (WORD)(12 + nUinLen + hashlen)); packFNACHeaderFull(&packet, ICQ_AVATAR_FAMILY, ICQ_AVATAR_GET_REQUEST, 0, dwCookie); packUID(&packet, dwUin, szUid); packByte(&packet, 1); // unknown, probably type of request: 1 = get icon :) packBuffer(&packet, hash, (unsigned short)hashlen); if (sendAvatarPacket(&packet, atsi)) { NetLog_Server("Request to get %d avatar image sent.", dwUin); return dwCookie; } FreeCookie(dwCookie); // sending failed, free resources SAFE_FREE(&ack->szFile); SAFE_FREE(&ack->hash); SAFE_FREE(&ack); } else LeaveCriticalSection(&cookieMutex); } // we failed to send request, or avatar thread not ready EnterCriticalSection(&cookieMutex); // wait for ready queue, reused cs { // check if any request for this user is not already in the queue avatarrequest* ar; int bYet = 0; ar = pendingRequests; while (ar) { if (ar->hContact == hContact) { // we found it, return error LeaveCriticalSection(&cookieMutex); NetLog_Server("Ignoring duplicate get %d avatar request.", dwUin); if (!AvatarsReady && !pendingAvatarsStart) { icq_requestnewfamily(ICQ_AVATAR_FAMILY, StartAvatarThread); pendingAvatarsStart = 1; } return 0; } ar = ar->pNext; } // add request to queue, processed after successful login ar = CreateAvatarRequest(1); // get avatar if (!ar) { // out of memory, go away LeaveCriticalSection(&cookieMutex); return 0; } ar->dwUin = dwUin; ar->szUid = null_strdup(szUid); ar->hContact = hContact; ar->hash = (char*)SAFE_MALLOC(hashlen); memcpy(ar->hash, hash, hashlen); // copy the data ar->hashlen = hashlen; ar->szFile = null_strdup(file); // duplicate the string ar->pNext = pendingRequests; pendingRequests = ar; } LeaveCriticalSection(&cookieMutex); NetLog_Server("Request to get %d avatar image added to queue.", dwUin); if (!AvatarsReady && !pendingAvatarsStart) { icq_requestnewfamily(0x10, StartAvatarThread); pendingAvatarsStart = 1; } return -1; // we added to queue */ return 0; }