INT_PTR CAimProto::GetAvatarInfo(WPARAM wParam, LPARAM lParam) { PROTO_AVATAR_INFORMATION *pai = (PROTO_AVATAR_INFORMATION*)lParam; pai->filename[0] = 0; pai->format = PA_FORMAT_UNKNOWN; if (getByte(AIM_KEY_DA, 0)) return GAIR_NOAVATAR; switch (get_avatar_filename(pai->hContact, pai->filename, _countof(pai->filename), NULL)) { case GAIR_SUCCESS: if (!(wParam & GAIF_FORCE) || m_state != 1) return GAIR_SUCCESS; case GAIR_WAITFOR: pai->format = ProtoGetAvatarFormat(pai->filename); break; default: return GAIR_NOAVATAR; } if (m_state == 1) { ForkThread(&CAimProto::avatar_request_thread, (void*)pai->hContact); return GAIR_WAITFOR; } return GAIR_NOAVATAR; }
INT_PTR GGPROTO::setmyavatar(WPARAM wParam, LPARAM lParam) { TCHAR *szFilename = (TCHAR*)lParam; if (!getByte(GG_KEY_ENABLEAVATARS, GG_KEYDEF_ENABLEAVATARS)) return -2; if (szFilename == NULL) { MessageBox(NULL, TranslateT("To remove your Gadu-Gadu avatar, you must use the gg.pl website."), m_tszUserName, MB_OK | MB_ICONINFORMATION); return -1; } int iAvType = ProtoGetAvatarFormat(szFilename); if ( iAvType == PA_FORMAT_UNKNOWN) { debugLogA("setmyavatar(): Failed to set user avatar. File %s has incompatible extension.", szFilename); return -1; } setByte(GG_KEY_AVATARTYPEPREV, getByte(GG_KEY_AVATARTYPE, -1)); setByte(GG_KEY_AVATARTYPE, (BYTE)iAvType); TCHAR szMyFilename[MAX_PATH]; getAvatarFilename(NULL, szMyFilename, _countof(szMyFilename)); if ( mir_tstrcmp(szFilename, szMyFilename) && !CopyFile(szFilename, szMyFilename, FALSE)) { debugLogA("setmyavatar(): Failed to set user avatar. File with type %d could not be created/overwritten.", iAvType); return -1; } setAvatar(szMyFilename); return 0; }
INT_PTR CVkProto::SvcGetAvatarInfo(WPARAM wParam, LPARAM lParam) { PROTO_AVATAR_INFORMATIONT* AI = (PROTO_AVATAR_INFORMATIONT*)lParam; ptrA szUrl( getStringA(AI->hContact, "AvatarUrl")); if (szUrl == NULL) return GAIR_NOAVATAR; TCHAR tszFileName[MAX_PATH]; GetAvatarFileName(AI->hContact, tszFileName, SIZEOF(tszFileName)); _tcsncpy(AI->filename, tszFileName, SIZEOF(AI->filename)); AI->format = ProtoGetAvatarFormat(AI->filename); if (::_taccess(AI->filename, 0) == 0) return GAIR_SUCCESS; if ( IsOnline()) { AsyncHttpRequest *pReq = new AsyncHttpRequest(); pReq->flags = NLHRF_NODUMP | NLHRF_REDIRECT; pReq->m_szUrl = szUrl; pReq->pUserInfo = (char*)AI->hContact; pReq->m_pFunc = &CVkProto::OnReceiveAvatar; pReq->requestType = REQUEST_GET; Push(pReq); debugLogA("Requested to read an avatar from '%s'", szUrl); return GAIR_WAITFOR; } debugLogA("No avatar"); return GAIR_NOAVATAR; }
INT_PTR CVkProto::SvcGetAvatarInfo(WPARAM, LPARAM lParam) { PROTO_AVATAR_INFORMATION* pai = (PROTO_AVATAR_INFORMATION*)lParam; ptrA szUrl(getStringA(pai->hContact, "AvatarUrl")); if (szUrl == NULL) return GAIR_NOAVATAR; TCHAR tszFileName[MAX_PATH]; GetAvatarFileName(pai->hContact, tszFileName, _countof(tszFileName)); _tcsncpy(pai->filename, tszFileName, _countof(pai->filename)); pai->format = ProtoGetAvatarFormat(pai->filename); if (::_taccess(pai->filename, 0) == 0 && !getBool(pai->hContact, "NeedNewAvatar")) return GAIR_SUCCESS; if (IsOnline()) { AsyncHttpRequest *pReq = new AsyncHttpRequest(); pReq->flags = NLHRF_NODUMP | NLHRF_REDIRECT; pReq->m_szUrl = szUrl; pReq->pUserInfo = new CVkSendMsgParam(pai->hContact); pReq->m_pFunc = &CVkProto::OnReceiveAvatar; pReq->requestType = REQUEST_GET; pReq->m_bApiReq = false; Push(pReq); debugLogA("Requested to read an avatar from '%s'", szUrl); return GAIR_WAITFOR; } debugLogA("No avatar"); return GAIR_NOAVATAR; }
DWORD CMraProto::MraAvatarsQueueGetAvatar(HANDLE hAvatarsQueueHandle, DWORD dwFlags, MCONTACT hContact, DWORD *pdwAvatarsQueueID, DWORD *pdwFormat, LPTSTR lpszPath) { DWORD dwRetCode = GAIR_NOAVATAR; if ( !hAvatarsQueueHandle) return GAIR_NOAVATAR; if ( !db_get_b(NULL, MRA_AVT_SECT_NAME, "Enable", MRA_AVT_DEFAULT_ENABLE)) return GAIR_NOAVATAR; if (IsContactChatAgent(hContact)) // @chat.agent conference return GAIR_NOAVATAR; BOOL bQueueAdd = TRUE;// check for updates MRA_AVATARS_QUEUE *pmraaqAvatarsQueue = (MRA_AVATARS_QUEUE*)hAvatarsQueueHandle; SYSTEMTIME stAvatarLastCheckTime; if ((dwFlags & GAIF_FORCE) == 0)// если флаг принудит. обновления, то даже не проверяем времени последнего обновления if (MraAvatarsGetContactTime(hContact, "AvatarLastCheckTime", &stAvatarLastCheckTime)) { CMStringW wszFileName; FILETIME ftCurrentTime, ftExpireTime; GetSystemTimeAsFileTime(&ftCurrentTime); SystemTimeToFileTime(&stAvatarLastCheckTime, &ftExpireTime); (*((DWORDLONG*)&ftExpireTime)) += (FILETIME_MINUTE*(DWORDLONG)db_get_dw(NULL, MRA_AVT_SECT_NAME, "CheckInterval", MRA_AVT_DEFAULT_CHK_INTERVAL)); if ((*((DWORDLONG*)&ftExpireTime)) > (*((DWORDLONG*)&ftCurrentTime))) if (MraAvatarsGetFileName(hAvatarsQueueHandle, hContact, GetContactAvatarFormat(hContact, PA_FORMAT_DEFAULT), wszFileName) == NO_ERROR) if (IsFileExist(wszFileName)) { // файл с аватаром существует и не устарел/не было комманды обновлять(просто запрос имени) if (lpszPath) { if (db_get_b(NULL, MRA_AVT_SECT_NAME, "ReturnAbsolutePath", MRA_AVT_DEFAULT_RET_ABC_PATH)) lstrcpyn(lpszPath, wszFileName, MAX_PATH); else PathToRelativeT(wszFileName, lpszPath); } if (pdwFormat) *pdwFormat = ProtoGetAvatarFormat(lpszPath); dwRetCode = GAIR_SUCCESS; bQueueAdd = FALSE; } } if (bQueueAdd || (dwFlags & GAIF_FORCE)) if (!MraAvatarsQueueAdd(hAvatarsQueueHandle, dwFlags, hContact, pdwAvatarsQueueID)) { MraAvatarsSetContactTime(hContact, "AvatarLastCheckTime", NULL); dwRetCode = GAIR_WAITFOR; } return dwRetCode; }
void StartFlash(HWND hwnd, ACCData* data) { if (!ServiceExists(MS_FAVATAR_MAKE)) return; int format; if (data->hContact != NULL) { format = db_get_w(data->hContact, "ContactPhoto", "Format", 0); } else if (data->proto[0] != '\0') { protoPicCacheEntry *ace = NULL; for (int i = 0; i < g_MyAvatars.getCount(); i++) { if (!lstrcmpA(data->proto, g_MyAvatars[i].szProtoname)) { ace = &g_MyAvatars[i]; break; } } if (ace != NULL && ace->szFilename != NULL) format = ProtoGetAvatarFormat(ace->szFilename); else format = 0; } else return; if (format != PA_FORMAT_XML && format != PA_FORMAT_SWF) return; FLASHAVATAR fa = {0}; fa.hContact = data->hContact; fa.cProto = data->proto; fa.hParentWindow = hwnd; fa.id = 1675; CallService(MS_FAVATAR_MAKE, (WPARAM)&fa, 0); if (fa.hWindow == NULL) return; data->showingFlash = TRUE; ResizeFlash(hwnd, data); SetBkgFlash(hwnd, data); }
/* void *p should always be a struct of type update_avatar */ void TwitterProto::UpdateAvatarWorker(void *p) { if(p == 0) return; std::auto_ptr<update_avatar> data( static_cast<update_avatar*>(p)); DBVARIANT dbv = {0}; // db_get_s returns 0 when it suceeds, so if this suceeds it will return 0, or false. // therefore if it returns 1, or true, we want to return as there is no such user. // as a side effect, dbv now has the username in it i think if(db_get_ts(data->hContact,m_szModuleName,TWITTER_KEY_UN,&dbv)) return; std::string ext = data->url.substr(data->url.rfind('.')); // finds the filetype of the avatar std::tstring filename = GetAvatarFolder() + _T('\\') + dbv.ptszVal + (TCHAR*)_A2T(ext.c_str()); // local filename and path db_free(&dbv); PROTO_AVATAR_INFORMATIONT ai = {sizeof(ai)}; ai.hContact = data->hContact; ai.format = ProtoGetAvatarFormat(filename.c_str()); if (ai.format == PA_FORMAT_UNKNOWN) { debugLogA( _T("***** Update avatar: Terminated for this contact, extension format unknown for %s"), data->url.c_str()); return; // lets just ignore unknown formats... if not it crashes miranda. should probably speak to borkra about this. } _tcsncpy(ai.filename,filename.c_str(),MAX_PATH); // puts the local file name in the avatar struct, to a max of 260 chars (as of now) debugLogA( _T("***** Updating avatar: %s"), data->url.c_str()); WaitForSingleObjectEx(avatar_lock_,INFINITE,true); if(CallService(MS_SYSTEM_TERMINATED,0,0)) // if miranda is shutting down... { debugLogA( _T("***** Terminating avatar update early: %s"),data->url.c_str()); return; } if(save_url(hAvatarNetlib_,data->url,filename)) { db_set_s(data->hContact,m_szModuleName,TWITTER_KEY_AV_URL,data->url.c_str()); ProtoBroadcastAck(data->hContact,ACKTYPE_AVATAR,ACKRESULT_SUCCESS,&ai,0); } else ProtoBroadcastAck(data->hContact,ACKTYPE_AVATAR,ACKRESULT_FAILED, &ai,0); ReleaseMutex(avatar_lock_); debugLogA( _T("***** Done avatar: %s"),data->url.c_str()); }
void CVkProto::SetAvatarUrl(MCONTACT hContact, LPCTSTR ptszUrl) { ptrT oldUrl( getTStringA(hContact, "AvatarUrl")); if (!lstrcmp(ptszUrl, oldUrl)) return; if (ptszUrl == NULL) { delSetting(hContact, "AvatarUrl"); ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, NULL, 0); } else { setTString(hContact, "AvatarUrl", ptszUrl); PROTO_AVATAR_INFORMATIONT AI = { sizeof(AI) }; AI.hContact = hContact; GetAvatarFileName(AI.hContact, AI.filename, SIZEOF(AI.filename)); AI.format = ProtoGetAvatarFormat(AI.filename); ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, (HANDLE)&AI, 0); } }
void CVkProto::SetAvatarUrl(MCONTACT hContact, CMString &tszUrl) { CMString oldUrl(getTStringA(hContact, "AvatarUrl")); if (tszUrl == oldUrl) return; if (tszUrl.IsEmpty()) { delSetting(hContact, "AvatarUrl"); ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, NULL); } else { setTString(hContact, "AvatarUrl", tszUrl); 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); } }
void CMraProto::MraAvatarsThreadProc(LPVOID lpParameter) { MRA_AVATARS_QUEUE *pmraaqAvatarsQueue = (MRA_AVATARS_QUEUE*)lpParameter; MRA_AVATARS_QUEUE_ITEM *pmraaqiAvatarsQueueItem; CMStringA szEmail, szServer; CMStringW wszFileName; BOOL bContinue, bKeepAlive, bUseKeepAliveConn, bFailed, bDownloadNew, bDefaultAvt; BYTE btBuff[BUFF_SIZE_RCV]; DWORD dwResultCode, dwAvatarFormat, dwReceived, dwServerPort, dwErrorCode; size_t dwAvatarSizeServer; FILETIME ftLastModifiedTimeServer, ftLastModifiedTimeLocal; SYSTEMTIME stAvatarLastModifiedTimeLocal; HANDLE hConnection = NULL; NETLIBSELECT nls = { 0 }; INTERNET_TIME itAvatarLastModifiedTimeServer; PROTO_AVATAR_INFORMATIONT pai; WCHAR szErrorText[2048]; nls.cbSize = sizeof(nls); pai.cbSize = sizeof(pai); InterlockedIncrement((volatile LONG*)&pmraaqAvatarsQueue->lThreadsRunningCount); while (InterlockedExchangeAdd((volatile LONG*)&pmraaqAvatarsQueue->bIsRunning, 0)) { if (FifoMTItemPop(pmraaqAvatarsQueue, NULL, (LPVOID*)&pmraaqiAvatarsQueueItem) != NO_ERROR) { // waiting until service stop or new task NETLIB_CLOSEHANDLE(hConnection); WaitForSingleObjectEx(pmraaqAvatarsQueue->hThreadEvent, MRA_AVT_DEFAULT_QE_CHK_INTERVAL, FALSE); continue; } /* Try download. */ bFailed = TRUE; bDownloadNew = FALSE; bDefaultAvt = FALSE; if (!DB_GetStringA(NULL, MRA_AVT_SECT_NAME, "Server", szServer)) szServer = MRA_AVT_DEFAULT_SERVER; dwServerPort = db_get_dw(NULL, MRA_AVT_SECT_NAME, "ServerPort", MRA_AVT_DEFAULT_SERVER_PORT); bUseKeepAliveConn = db_get_b(NULL, MRA_AVT_SECT_NAME, "UseKeepAliveConn", MRA_AVT_DEFAULT_USE_KEEPALIVE_CONN); if (mraGetStringA(pmraaqiAvatarsQueueItem->hContact, "e-mail", szEmail)) { szEmail.MakeLower(); int iStart = 0; CMStringA szUser = szEmail.Tokenize("@", iStart); CMStringA szDomain = szEmail.Tokenize("@", iStart); if (!szUser.IsEmpty() && !szDomain.IsEmpty()) { ProtoBroadcastAck(pmraaqiAvatarsQueueItem->hContact, ACKTYPE_AVATAR, ACKRESULT_CONNECTING, NULL, 0); if (hConnection == NULL) hConnection = MraAvatarsHttpConnect(pmraaqAvatarsQueue->hNetlibUser, szServer, dwServerPort); if (hConnection) { ProtoBroadcastAck(pmraaqiAvatarsQueueItem->hContact, ACKTYPE_AVATAR, ACKRESULT_CONNECTED, NULL, 0); ProtoBroadcastAck(pmraaqiAvatarsQueueItem->hContact, ACKTYPE_AVATAR, ACKRESULT_SENTREQUEST, NULL, 0); if (!MraAvatarsHttpTransaction(hConnection, REQUEST_HEAD, szUser, szDomain, szServer, MAHTRO_AVTMRIM, bUseKeepAliveConn, &dwResultCode, &bKeepAlive, &dwAvatarFormat, &dwAvatarSizeServer, &itAvatarLastModifiedTimeServer)) { switch (dwResultCode) { case 200: if (MraAvatarsGetContactTime(pmraaqiAvatarsQueueItem->hContact, "AvatarLastModifiedTime", &stAvatarLastModifiedTimeLocal)) { SystemTimeToFileTime(&itAvatarLastModifiedTimeServer.stTime, &ftLastModifiedTimeServer); SystemTimeToFileTime(&stAvatarLastModifiedTimeLocal, &ftLastModifiedTimeLocal); if ((*((DWORDLONG*)&ftLastModifiedTimeServer)) != (*((DWORDLONG*)&ftLastModifiedTimeLocal))) {// need check for update bDownloadNew = TRUE; //ProtoBroadcastAck(pmraaqiAvatarsQueueItem->hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, 0, 0); } else {// avatar is valid if (MraAvatarsGetFileName(pmraaqAvatarsQueue, pmraaqiAvatarsQueueItem->hContact, dwAvatarFormat, wszFileName) == NO_ERROR) { if (IsFileExist(wszFileName)) bFailed = FALSE; else bDownloadNew = TRUE; } } } else // need update bDownloadNew = TRUE; break; case 404:// return def avatar if (MraAvatarsGetFileName((HANDLE)pmraaqAvatarsQueue, NULL, PA_FORMAT_DEFAULT, wszFileName) == NO_ERROR) { if (IsFileExist(wszFileName)) { dwAvatarFormat = ProtoGetAvatarFormat(wszFileName); bFailed = FALSE; } else//loading default avatar bDownloadNew = TRUE; bDefaultAvt = TRUE; } break; default: mir_sntprintf(szErrorText, SIZEOF(szErrorText), TranslateT("Avatars: server return HTTP code: %lu"), dwResultCode); ShowFormattedErrorMessage(szErrorText, NO_ERROR); break; } } if (bUseKeepAliveConn == FALSE || bKeepAlive == FALSE) NETLIB_CLOSEHANDLE(hConnection); } if (bDownloadNew) { if (hConnection == NULL) hConnection = MraAvatarsHttpConnect(pmraaqAvatarsQueue->hNetlibUser, szServer, dwServerPort); if (hConnection) { ProtoBroadcastAck(pmraaqiAvatarsQueueItem->hContact, ACKTYPE_AVATAR, ACKRESULT_DATA, NULL, 0); if (MraAvatarsHttpTransaction(hConnection, REQUEST_GET, szUser, szDomain, szServer, MAHTRO_AVT, bUseKeepAliveConn, &dwResultCode, &bKeepAlive, &dwAvatarFormat, &dwAvatarSizeServer, &itAvatarLastModifiedTimeServer) == NO_ERROR && dwResultCode == 200) { if (bDefaultAvt) dwAvatarFormat = PA_FORMAT_DEFAULT; if (!MraAvatarsGetFileName(pmraaqAvatarsQueue, pmraaqiAvatarsQueueItem->hContact, dwAvatarFormat, wszFileName)) { HANDLE hFile = CreateFile(wszFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { DWORD dwWritten = 0; bContinue = TRUE; nls.dwTimeout = (1000 * db_get_dw(NULL, MRA_AVT_SECT_NAME, "TimeOutReceive", MRA_AVT_DEFAULT_TIMEOUT_RECV)); nls.hReadConns[0] = hConnection; while (bContinue) { switch (CallService(MS_NETLIB_SELECT, 0, (LPARAM)&nls)) { case SOCKET_ERROR: case 0:// Time out dwErrorCode = GetLastError(); ShowFormattedErrorMessage(L"Avatars: error on receive file data", dwErrorCode); bContinue = FALSE; break; case 1: dwReceived = Netlib_Recv(hConnection, (LPSTR)&btBuff, SIZEOF(btBuff), 0); if (dwReceived == 0 || dwReceived == SOCKET_ERROR) { dwErrorCode = GetLastError(); ShowFormattedErrorMessage(L"Avatars: error on receive file data", dwErrorCode); bContinue = FALSE; } else { if (WriteFile(hFile, (LPVOID)&btBuff, dwReceived, &dwReceived, NULL)) { dwWritten += dwReceived; if (dwWritten >= dwAvatarSizeServer) bContinue = FALSE; } else { dwErrorCode = GetLastError(); ShowFormattedErrorMessage(L"Avatars: cant write file data, error", dwErrorCode); bContinue = FALSE; } } break; } } CloseHandle(hFile); bFailed = FALSE; } else { dwErrorCode = GetLastError(); mir_sntprintf(szErrorText, SIZEOF(szErrorText), TranslateT("Avatars: can't open file %s, error"), wszFileName); ShowFormattedErrorMessage(szErrorText, dwErrorCode); } } } else _CrtDbgBreak(); if (bUseKeepAliveConn == FALSE || bKeepAlive == FALSE) NETLIB_CLOSEHANDLE(hConnection); } } } } if (bFailed) { DeleteFile(wszFileName); pai.hContact = pmraaqiAvatarsQueueItem->hContact; pai.format = PA_FORMAT_UNKNOWN; pai.filename[0] = 0; ProtoBroadcastAck(pmraaqiAvatarsQueueItem->hContact, ACKTYPE_AVATAR, ACKRESULT_FAILED, (HANDLE)&pai, 0); } else { pai.hContact = pmraaqiAvatarsQueueItem->hContact; pai.format = dwAvatarFormat; if (db_get_b(NULL, MRA_AVT_SECT_NAME, "ReturnAbsolutePath", MRA_AVT_DEFAULT_RET_ABC_PATH)) lstrcpyn(pai.filename, wszFileName, SIZEOF(pai.filename)); else PathToRelativeT(wszFileName, pai.filename); if (bDefaultAvt) dwAvatarFormat = PA_FORMAT_DEFAULT; SetContactAvatarFormat(pmraaqiAvatarsQueueItem->hContact, dwAvatarFormat); MraAvatarsSetContactTime(pmraaqiAvatarsQueueItem->hContact, "AvatarLastModifiedTime", &itAvatarLastModifiedTimeServer.stTime); // write owner avatar file name to DB if (pmraaqiAvatarsQueueItem->hContact == NULL) // proto avatar CallService(MS_AV_REPORTMYAVATARCHANGED, (WPARAM)m_szModuleName, 0); ProtoBroadcastAck(pmraaqiAvatarsQueueItem->hContact, ACKTYPE_AVATAR, ACKRESULT_SUCCESS, (HANDLE)&pai, 0); } mir_free(pmraaqiAvatarsQueueItem); } InterlockedDecrement((volatile LONG*)&pmraaqAvatarsQueue->lThreadsRunningCount); }
INT_PTR GGPROTO::getavatarinfo(WPARAM wParam, LPARAM lParam) { PROTO_AVATAR_INFORMATION *pai = (PROTO_AVATAR_INFORMATION *)lParam; pai->filename[0] = 0; pai->format = PA_FORMAT_UNKNOWN; uin_t uin = (uin_t)getDword(pai->hContact, GG_KEY_UIN, 0); if (!uin) { debugLogA("getavatarinfo(): Incoming request for avatar information. No uin found. return GAIR_NOAVATAR"); return GAIR_NOAVATAR; } if (!getByte(GG_KEY_ENABLEAVATARS, GG_KEYDEF_ENABLEAVATARS)) { debugLogA("getavatarinfo(): Incoming request for avatar information. GG_KEY_ENABLEAVATARS == 0. return GAIR_NOAVATAR"); return GAIR_NOAVATAR; } //directly check if contact has protected user avatar set by AVS, and if yes return it as protocol avatar DBVARIANT dbv; if (!db_get_ts(pai->hContact, "ContactPhoto", "Backup", &dbv)) { if ((mir_tstrlen(dbv.ptszVal)>0) && db_get_b(pai->hContact, "ContactPhoto", "Locked", 0)){ debugLogA("getavatarinfo(): Incoming request for avatar information. Contact has assigned Locked ContactPhoto. return GAIR_SUCCESS"); _tcscpy_s(pai->filename, _countof(pai->filename) ,dbv.ptszVal); pai->format = ProtoGetAvatarFormat(pai->filename); db_free(&dbv); return GAIR_SUCCESS; } db_free(&dbv); } if (!getByte(pai->hContact, GG_KEY_AVATARREQUESTED, GG_KEYDEF_AVATARREQUESTED)) { requestAvatarInfo(pai->hContact, 1); if ((wParam & GAIF_FORCE) != 0) { debugLogA("getavatarinfo(): Incoming request for avatar information. uin=%d. requestAvatarInfo() fired. return GAIR_WAITFOR", uin); return GAIR_WAITFOR; } else { debugLogA("getavatarinfo(): Incoming request for avatar information. uin=%d. requestAvatarInfo() fired. return GAIR_NOAVATAR", uin); return GAIR_NOAVATAR; } } pai->format = getByte(pai->hContact, GG_KEY_AVATARTYPE, GG_KEYDEF_AVATARTYPE); ptrA AvatarHash(NULL); ptrA AvatarURL( getStringA(pai->hContact, GG_KEY_AVATARURL)); ptrA AvatarTs( getStringA(pai->hContact, GG_KEY_AVATARTS)); if (AvatarURL != NULL && AvatarTs != NULL) { char *AvatarName = strrchr(AvatarURL, '/'); AvatarName++; char AvatarNameWithTS[128]; mir_snprintf(AvatarNameWithTS, "%s%s", AvatarName, AvatarTs); AvatarHash = gg_avatarhash(AvatarNameWithTS); } ptrA AvatarSavedHash( getStringA(pai->hContact, GG_KEY_AVATARHASH)); if (AvatarHash != NULL && AvatarSavedHash != NULL) { getAvatarFilename(pai->hContact, pai->filename, _countof(pai->filename)); if (!mir_strcmp(AvatarHash, AvatarSavedHash)) { if (_taccess(pai->filename, 0) == 0){ debugLogA("getavatarinfo(): Incoming request for avatar information. uin=%d. Avatar hash unchanged. return GAIR_SUCCESS", uin); return GAIR_SUCCESS; } requestAvatarTransfer(pai->hContact, AvatarURL); debugLog(_T("getavatarinfo(): Incoming request for avatar information. uin=%d. Avatar hash unchanged but file %s does not exist. errno=%d: %s. requestAvatarTransfer() fired. return GAIR_WAITFOR"), uin, pai->filename, errno, strerror(errno)); return GAIR_WAITFOR; } if ((wParam & GAIF_FORCE) != 0) { if (_tremove(pai->filename) != 0){ debugLog(_T("getavatarinfo(): refresh. _tremove 1 file %s error. errno=%d: %s"), pai->filename, errno, strerror(errno)); TCHAR error[512]; mir_sntprintf(error, TranslateT("Cannot remove old avatar file before refresh. ERROR: %d: %s\n%s"), errno, _tcserror(errno), pai->filename); showpopup(m_tszUserName, error, GG_POPUP_ERROR); } setString(pai->hContact, GG_KEY_AVATARHASH, AvatarHash); requestAvatarTransfer(pai->hContact, AvatarURL); debugLogA("getavatarinfo(): Incoming request for avatar information. uin=%d. Avatar hash changed, requestAvatarTransfer() fired. return GAIR_WAITFOR", uin); return GAIR_WAITFOR; } } else if ((wParam & GAIF_FORCE) != 0) { if (AvatarHash == NULL && AvatarSavedHash != NULL) { getAvatarFilename(pai->hContact, pai->filename, _countof(pai->filename)); if (_tremove(pai->filename) != 0){ debugLog(_T("getavatarinfo(): delete. _tremove file %s error. errno=%d: %s"), pai->filename, errno, strerror(errno)); TCHAR error[512]; mir_sntprintf(error, TranslateT("Cannot remove old avatar file. ERROR: %d: %s\n%s"), errno, _tcserror(errno), pai->filename); showpopup(m_tszUserName, error, GG_POPUP_ERROR); } delSetting(pai->hContact, GG_KEY_AVATARHASH); delSetting(pai->hContact, GG_KEY_AVATARURL); delSetting(pai->hContact, GG_KEY_AVATARTYPE); debugLogA("getavatarinfo(): Incoming request for avatar information. Contact %d deleted avatar. return GAIR_NOAVATAR", uin); } else if (AvatarHash != NULL && AvatarSavedHash == NULL) { setString(pai->hContact, GG_KEY_AVATARHASH, AvatarHash); requestAvatarTransfer(pai->hContact, AvatarURL); debugLogA("getavatarinfo(): Incoming request for avatar information. Contact %d set avatar. requestAvatarTransfer() fired. return GAIR_WAITFOR", uin); return GAIR_WAITFOR; } else debugLogA("getavatarinfo(): Incoming request for avatar information. uin=%d. AvatarHash==AvatarSavedHash==NULL, with GAIF_FORCE param. return GAIR_NOAVATAR", uin); } else debugLogA("getavatarinfo(): Incoming request for avatar information. uin=%d. AvatarHash==null or AvatarSavedHash==null, but no GAIF_FORCE param. return GAIR_NOAVATAR", uin); return GAIR_NOAVATAR; }
INT_PTR CMsnProto::GetAvatarInfo(WPARAM wParam, LPARAM lParam) { PROTO_AVATAR_INFORMATION *pai = (PROTO_AVATAR_INFORMATION*)lParam; TCHAR filename[MAX_PATH]; MsnContact *cont = NULL; if (pai->hContact) { cont = Lists_Get(pai->hContact); if (cont == NULL) return GAIR_NOAVATAR; /* if ((cont->cap1 & 0xf0000000) == 0) return GAIR_NOAVATAR; */ } if (pai->hContact == NULL || _stricmp(cont->email, MyOptions.szEmail) == 0) { MSN_GetAvatarFileName(NULL, filename, _countof(filename), NULL); pai->format = ProtoGetAvatarFormat(filename); if (pai->format != PA_FORMAT_UNKNOWN) mir_tstrcpy(pai->filename, filename); return pai->format == PA_FORMAT_UNKNOWN ? GAIR_NOAVATAR : GAIR_SUCCESS; } char *szContext; DBVARIANT dbv; if (getString(pai->hContact, pai->hContact ? "PictContext" : "PictObject", &dbv) == 0) { szContext = (char*)NEWSTR_ALLOCA(dbv.pszVal); db_free(&dbv); } else return GAIR_NOAVATAR; MSN_GetAvatarFileName(pai->hContact, filename, _countof(filename), NULL); pai->format = ProtoGetAvatarFormat(filename); if (pai->format != PA_FORMAT_UNKNOWN) { bool needupdate = true; if (getString(pai->hContact, "PictSavedContext", &dbv) == 0) { needupdate = mir_strcmp(dbv.pszVal, szContext) != 0; db_free(&dbv); } if (needupdate) { setString(pai->hContact, "PictSavedContext", szContext); // Store also avatar hash char* szAvatarHash = MSN_GetAvatarHash(szContext); if (szAvatarHash != NULL) { setString(pai->hContact, "AvatarSavedHash", szAvatarHash); mir_free(szAvatarHash); } } mir_tstrcpy(pai->filename, filename); return GAIR_SUCCESS; } if ((wParam & GAIF_FORCE) != 0 && pai->hContact != NULL) { if (avsPresent < 0) avsPresent = ServiceExists(MS_AV_SETMYAVATAR) != 0; if (!avsPresent) return GAIR_NOAVATAR; WORD wStatus = getWord(pai->hContact, "Status", ID_STATUS_OFFLINE); if (wStatus == ID_STATUS_OFFLINE) { delSetting(pai->hContact, "AvatarHash"); PROTO_AVATAR_INFORMATION *fakeAI = new PROTO_AVATAR_INFORMATION; *fakeAI = *pai; ForkThread(&CMsnProto::sttFakeAvatarAck, fakeAI); } else if (!getString(pai->hContact, "AvatarUrl", &dbv)) { pushAvatarRequest(pai->hContact, dbv.pszVal); db_free(&dbv); } #ifdef OBSOLETE else if (p2p_getAvatarSession(pai->hContact) == NULL) { filetransfer* ft = new filetransfer(this); ft->std.hContact = pai->hContact; ft->p2p_object = mir_strdup(szContext); MSN_GetAvatarFileName(pai->hContact, filename, _countof(filename), _T("unk")); ft->std.tszCurrentFile = mir_tstrdup(filename); p2p_invite(MSN_APPID_AVATAR, ft, NULL); } #endif return GAIR_WAITFOR; } return GAIR_NOAVATAR; }
static int InternalSetMyAvatar(char *protocol, TCHAR *szFinalName, SetMyAvatarHookData &data, BOOL allAcceptXML, BOOL allAcceptSWF) { int format = ProtoGetAvatarFormat(szFinalName); if (format == PA_FORMAT_UNKNOWN || _taccess(szFinalName, 4) == -1) return -3; // file exists... HBITMAP hBmp = NULL; if (format == PA_FORMAT_SWF) { if (!allAcceptSWF) return -4; } else if (format == PA_FORMAT_XML) { if (!allAcceptXML) return -4; } else { // Try to open if is not a flash or XML hBmp = (HBITMAP)CallService(MS_IMG_LOAD, (WPARAM)szFinalName, IMGL_TCHAR); if (hBmp == NULL) return -4; } SetIgnoreNotify(protocol, TRUE); int ret = 0; if (protocol != NULL) { ret = SetProtoMyAvatar(protocol, hBmp, szFinalName, format, data.square, data.grow); if (ret == 0) { DeleteGlobalUserAvatar(); db_set_b(NULL, AVS_MODULE, "GlobalUserAvatarNotConsistent", 1); } } else { int count; PROTOACCOUNT **accs; ProtoEnumAccounts(&count, &accs); for (int i = 0; i < count; i++) { if (!ProtoServiceExists(accs[i]->szModuleName, PS_SETMYAVATAR)) continue; if (!Proto_IsAvatarsEnabled(accs[i]->szModuleName)) continue; int retTmp = SetProtoMyAvatar(accs[i]->szModuleName, hBmp, szFinalName, format, data.square, data.grow); if (retTmp != 0) ret = retTmp; } DeleteGlobalUserAvatar(); if (ret) db_set_b(NULL, AVS_MODULE, "GlobalUserAvatarNotConsistent", 1); else { // Copy avatar file to store as global one TCHAR globalFile[1024]; BOOL saved = TRUE; if (FoldersGetCustomPathT(hGlobalAvatarFolder, globalFile, SIZEOF(globalFile), _T(""))) { mir_sntprintf(globalFile, SIZEOF(globalFile), _T("%s%s"), g_szDataPath, _T("GlobalAvatar")); CreateDirectory(globalFile, NULL); } TCHAR *ext = _tcsrchr(szFinalName, _T('.')); // Can't be NULL here if (format == PA_FORMAT_XML || format == PA_FORMAT_SWF) { mir_sntprintf(globalFile, SIZEOF(globalFile), _T("%s\\my_global_avatar%s"), globalFile, ext); CopyFile(szFinalName, globalFile, FALSE); } else { // Resize (to avoid too big avatars) ResizeBitmap rb = { 0 }; rb.size = sizeof(ResizeBitmap); rb.hBmp = hBmp; rb.max_height = 300; rb.max_width = 300; rb.fit = (data.grow ? 0 : RESIZEBITMAP_FLAG_DONT_GROW) | (data.square ? RESIZEBITMAP_MAKE_SQUARE : RESIZEBITMAP_KEEP_PROPORTIONS); HBITMAP hBmpTmp = (HBITMAP)CallService(MS_IMG_RESIZE, WPARAM(&rb), 0); // Check if need to resize if (hBmpTmp == hBmp || hBmpTmp == NULL) { // Use original image mir_sntprintf(globalFile, SIZEOF(globalFile), _T("%s\\my_global_avatar%s"), globalFile, ext); CopyFile(szFinalName, globalFile, FALSE); } else { // Save as PNG mir_sntprintf(globalFile, SIZEOF(globalFile), _T("%s\\my_global_avatar.png"), globalFile); if (BmpFilterSaveBitmap(hBmpTmp, globalFile, 0)) saved = FALSE; DeleteObject(hBmpTmp); } } if (saved) { TCHAR relFile[1024]; if (PathToRelativeT(globalFile, relFile, g_szDataPath)) db_set_ts(NULL, AVS_MODULE, "GlobalUserAvatarFile", relFile); else db_set_ts(NULL, AVS_MODULE, "GlobalUserAvatarFile", globalFile); db_set_b(NULL, AVS_MODULE, "GlobalUserAvatarNotConsistent", 0); } else db_set_b(NULL, AVS_MODULE, "GlobalUserAvatarNotConsistent", 1); } } DeleteObject(hBmp); SetIgnoreNotify(protocol, FALSE); ReportMyAvatarChanged(WPARAM((protocol == NULL) ? "" : protocol), 0); return ret; }
void StartAnimatedGif(HWND hwnd, ACCData* data) { if (fei == NULL) return; int x, y; AVATARCACHEENTRY *ace = NULL; if (data->hContact != NULL) ace = (AVATARCACHEENTRY *) GetAvatarBitmap((WPARAM) data->hContact, 0); else ace = (AVATARCACHEENTRY *) GetMyAvatar(0, (LPARAM) data->proto); if (ace == NULL) return; int format = ProtoGetAvatarFormat(ace->szFilename); if (format != PA_FORMAT_GIF) return; FREE_IMAGE_FORMAT fif = fei->FI_GetFileTypeT(ace->szFilename, 0); if (fif == FIF_UNKNOWN) fif = fei->FI_GetFIFFromFilenameT(ace->szFilename); data->ag.multi = fei->FI_OpenMultiBitmapT(fif, ace->szFilename, FALSE, TRUE, FALSE, GIF_LOAD256); if (data->ag.multi == NULL) return; data->ag.frameCount = fei->FI_GetPageCount(data->ag.multi); if (data->ag.frameCount <= 1) goto ERR; if (!AnimatedGifGetData(data)) goto ERR; //allocate entire logical area data->ag.dib = fei->FI_Allocate(data->ag.logicalWidth, data->ag.logicalHeight, 32, 0, 0, 0); if (data->ag.dib == NULL) goto ERR; //fill with background color to start for (y = 0; y < data->ag.logicalHeight; y++) { RGBQUAD *scanline = (RGBQUAD *) fei->FI_GetScanLine(data->ag.dib, y); for (x = 0; x < data->ag.logicalWidth; x++) *scanline++ = data->ag.background; } data->ag.hbms = (HBITMAP *) malloc(sizeof(HBITMAP) * data->ag.frameCount); memset(data->ag.hbms, 0, sizeof(HBITMAP) * data->ag.frameCount); data->ag.times = (int *) malloc(sizeof(int) * data->ag.frameCount); memset(data->ag.times, 0, sizeof(int) * data->ag.frameCount); AnimatedGifMountFrame(data, 0); data->showingAnimatedGif = TRUE; return; ERR: fei->FI_CloseMultiBitmap(data->ag.multi, 0); data->ag.multi = NULL; }