From 3b55a62fdcb1f8222de3c2c8fbed530792c419a0 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Fri, 12 Oct 2012 14:53:57 +0000 Subject: GTalkExt, ICQ, IRC, Jabber: folders restructurization git-svn-id: http://svn.miranda-ng.org/main/trunk@1890 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/IcqOscarJ/src/icqosc_svcs.cpp | 816 ++++++++++++++++++++++++++++++++ 1 file changed, 816 insertions(+) create mode 100644 protocols/IcqOscarJ/src/icqosc_svcs.cpp (limited to 'protocols/IcqOscarJ/src/icqosc_svcs.cpp') diff --git a/protocols/IcqOscarJ/src/icqosc_svcs.cpp b/protocols/IcqOscarJ/src/icqosc_svcs.cpp new file mode 100644 index 0000000000..ee6dd1731c --- /dev/null +++ b/protocols/IcqOscarJ/src/icqosc_svcs.cpp @@ -0,0 +1,816 @@ +// ---------------------------------------------------------------------------80 +// ICQ plugin for Miranda Instant Messenger +// ________________________________________ +// +// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede +// Copyright © 2001-2002 Jon Keating, Richard Hughes +// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater +// Copyright © 2004-2010 Joe Kucera +// +// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// ----------------------------------------------------------------------------- +// DESCRIPTION: +// +// High-level code for exported API services +// +// ----------------------------------------------------------------------------- +#include "icqoscar.h" + + +INT_PTR CIcqProto::AddServerContact(WPARAM wParam, LPARAM lParam) +{ + DWORD dwUin; + uid_str szUid; + + if (!m_bSsiEnabled) return 0; + + // Does this contact have a UID? + if (!getContactUid((HANDLE)wParam, &dwUin, &szUid) && !getSettingWord((HANDLE)wParam, DBSETTING_SERVLIST_ID, 0) && !getSettingWord((HANDLE)wParam, DBSETTING_SERVLIST_IGNORE, 0)) + { /// TODO: remove possible 0x6A TLV in contact server-list data!!! + // Read group from DB + char *pszGroup = getContactCListGroup((HANDLE)wParam); + + servlistAddContact((HANDLE)wParam, pszGroup); + SAFE_FREE((void**)&pszGroup); + } + return 0; +} + + +static int LookupDatabaseSetting(const FieldNamesItem* table, int code, DBVARIANT *dbv, BYTE type) +{ + char *text = LookupFieldName(table, code); + + if (!text) + { + dbv->type = DBVT_DELETED; + return 1; + } + + if (type == DBVT_ASCIIZ) + { + dbv->pszVal = mir_strdup(Translate(text)); + dbv->type = DBVT_ASCIIZ; + } + else if (type == DBVT_UTF8 || !type) + { + char tmp[MAX_PATH]; + + dbv->pszVal = mir_strdup(ICQTranslateUtfStatic(text, tmp, MAX_PATH)); + dbv->type = DBVT_UTF8; + } + else if (type == DBVT_WCHAR) + { + WCHAR* wtext = make_unicode_string(text); + + dbv->pwszVal = mir_wstrdup(TranslateW(wtext)); + dbv->type = DBVT_WCHAR; + + SAFE_FREE((void**)&wtext); + } + return 0; // Success +} + +INT_PTR CIcqProto::GetInfoSetting(WPARAM wParam, LPARAM lParam) +{ + DBCONTACTGETSETTING *cgs = (DBCONTACTGETSETTING*)lParam; + BYTE type = cgs->pValue->type; + + cgs->pValue->type = 0; // original type without conversion + INT_PTR rc = CallService(MS_DB_CONTACT_GETSETTING_STR, wParam, lParam); + + if (!rc) + { // Success + DBVARIANT dbv; + + memcpy(&dbv, cgs->pValue, sizeof(DBVARIANT)); + + if (dbv.type == DBVT_BLOB) + { + cgs->pValue->pbVal = (BYTE*)mir_alloc(dbv.cpbVal); + + memcpy(cgs->pValue->pbVal, dbv.pbVal, dbv.cpbVal); + } + else if (dbv.type == DBVT_ASCIIZ || dbv.type == DBVT_UTF8) + { // convert to the desired type + if (!type) + type = dbv.type; + + if (dbv.type == type) + { // type is correct, only move it to miranda's heap + cgs->pValue->pszVal = mir_strdup(dbv.pszVal); + } + else if (type == DBVT_WCHAR) + { + if (dbv.type != DBVT_UTF8) + { + int len = MultiByteToWideChar(CP_ACP, 0, dbv.pszVal, -1, NULL, 0); + cgs->pValue->pwszVal = (WCHAR*)mir_alloc((len + 1)*sizeof(WCHAR)); + if (cgs->pValue->pwszVal == NULL) + rc = 1; + else + { + MultiByteToWideChar(CP_ACP, 0, dbv.pszVal, -1, cgs->pValue->pwszVal, len); + cgs->pValue->pwszVal[len] = '\0'; + } + } + else + { + char *savePtr = dbv.pszVal ? strcpy((char*)_alloca(strlennull(dbv.pszVal) + 1), dbv.pszVal) : NULL; + if (!mir_utf8decode(savePtr, &cgs->pValue->pwszVal)) + rc = 1; + } + } + else if (type == DBVT_UTF8) + { + cgs->pValue->pszVal = mir_utf8encode(dbv.pszVal); + if (cgs->pValue->pszVal == NULL) + rc = 1; + } + else if (type == DBVT_ASCIIZ) + { + cgs->pValue->pszVal = mir_strdup(dbv.pszVal); + mir_utf8decode(cgs->pValue->pszVal, NULL); + } + + cgs->pValue->type = type; + } + else if (!strcmpnull(cgs->szModule, m_szModuleName) && (dbv.type == DBVT_BYTE || dbv.type == DBVT_WORD || dbv.type == DBVT_DWORD)) + { + int code = (dbv.type == DBVT_BYTE) ? dbv.bVal : ((dbv.type == DBVT_WORD) ? dbv.wVal : dbv.dVal); + + if (!strcmpnull(cgs->szSetting, "Language1") || !strcmpnull(cgs->szSetting, "Language2") || !strcmpnull(cgs->szSetting, "Language3")) + rc = LookupDatabaseSetting(languageField, code, cgs->pValue, type); + else if (!strcmpnull(cgs->szSetting, "Country") || !strcmpnull(cgs->szSetting, "OriginCountry") || !strcmpnull(cgs->szSetting, "CompanyCountry")) + { + if (code == 420) code = 42; // conversion of obsolete codes (OMG!) + else if (code == 421) code = 4201; + else if (code == 102) code = 1201; + rc = LookupDatabaseSetting(countryField, code, cgs->pValue, type); + } + else if (!strcmpnull(cgs->szSetting, "Gender")) + rc = LookupDatabaseSetting(genderField, code, cgs->pValue, type); + else if (!strcmpnull(cgs->szSetting, "MaritalStatus")) + rc = LookupDatabaseSetting(maritalField, code, cgs->pValue, type); + else if (!strcmpnull(cgs->szSetting, "StudyLevel")) + rc = LookupDatabaseSetting(studyLevelField, code, cgs->pValue, type); + else if (!strcmpnull(cgs->szSetting, "CompanyIndustry")) + rc = LookupDatabaseSetting(industryField, code, cgs->pValue, type); + else if (!strcmpnull(cgs->szSetting, "Interest0Cat") || !strcmpnull(cgs->szSetting, "Interest1Cat") || !strcmpnull(cgs->szSetting, "Interest2Cat") || !strcmpnull(cgs->szSetting, "Interest3Cat")) + rc = LookupDatabaseSetting(interestsField, code, cgs->pValue, type); + } + // Release database memory + ICQFreeVariant(&dbv); + } + + return rc; +} + + +INT_PTR CIcqProto::ChangeInfoEx(WPARAM wParam, LPARAM lParam) +{ + if (icqOnline() && wParam) + { + PBYTE buf = NULL; + int buflen = 0; + BYTE b; + + // userinfo + ppackTLVWord(&buf, &buflen, 0x1C2, (WORD)GetACP()); + + if (wParam & CIXT_CONTACT) + { // contact information + BYTE *pBlock = NULL; + int cbBlock = 0; + int nItems = 0; + + // Emails + nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "e-mail0", 0x78, 0x64, 0x00); + nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "e-mail1", 0x78, 0x64, 0x00); + nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "e-mail2", 0x78, 0x64, 0x00); + ppackTLVBlockItems(&buf, &buflen, 0x8C, &nItems, &pBlock, (WORD*)&cbBlock, FALSE); + + // Phones + nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "Phone", 0x6E, 0x64, 0x01); + nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "CompanyPhone", 0x6E, 0x64, 0x02); + nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "Cellular", 0x6E, 0x64, 0x03); + nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "Fax", 0x6E, 0x64, 0x04); + nItems += ppackTLVWordStringItemFromDB(&pBlock, &cbBlock, "CompanyFax", 0x6E, 0x64, 0x05); + ppackTLVBlockItems(&buf, &buflen, 0xC8, &nItems, &pBlock, (WORD*)&cbBlock, FALSE); + + ppackTLVByte(&buf, &buflen, 0x1EA, getSettingByte(NULL, "AllowSpam", 0)); + } + + if (wParam & CIXT_BASIC) + { // upload basic user info + ppackTLVStringUtfFromDB(&buf, &buflen, "Nick", 0x78); + ppackTLVStringUtfFromDB(&buf, &buflen, "FirstName", 0x64); + ppackTLVStringUtfFromDB(&buf, &buflen, "LastName", 0x6E); + ppackTLVStringUtfFromDB(&buf, &buflen, "About", 0x186); + } + + if (wParam & CIXT_MORE) + { + b = getSettingByte(NULL, "Gender", 0); + ppackTLVByte(&buf, &buflen, 0x82, (BYTE)(b ? (b == 'M' ? 2 : 1) : 0)); + + ppackTLVDateFromDB(&buf, &buflen, "BirthYear", "BirthMonth", "BirthDay", 0x1A4); + + ppackTLVWord(&buf, &buflen, 0xAA, getSettingByte(NULL, "Language1", 0)); + ppackTLVWord(&buf, &buflen, 0xB4, getSettingByte(NULL, "Language2", 0)); + ppackTLVWord(&buf, &buflen, 0xBE, getSettingByte(NULL, "Language3", 0)); + + ppackTLVWord(&buf, &buflen, 0x12C, getSettingByte(NULL, "MaritalStatus", 0)); + } + + if (wParam & CIXT_WORK) + { + BYTE *pBlock = NULL; + int cbBlock = 0; + int nItems = 1; + + // Jobs + ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "CompanyPosition", 0x64); + ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "Company", 0x6E); + ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "CompanyDepartment", 0x7D); + ppackTLVStringFromDB(&pBlock, &cbBlock, "CompanyHomepage", 0x78); + ppackTLVWord(&pBlock, &cbBlock, 0x82, getSettingWord(NULL, "CompanyIndustry", 0)); + ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "CompanyStreet", 0xAA); + ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "CompanyCity", 0xB4); + ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "CompanyState", 0xBE); + ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "CompanyZIP", 0xC8); + ppackTLVDWord(&pBlock, &cbBlock, 0xD2, getSettingWord(NULL, "CompanyCountry", 0)); + /// TODO: pack unknown data (need to preserve them in Block Items) + ppackTLVBlockItems(&buf, &buflen, 0x118, &nItems, &pBlock, (WORD*)&cbBlock, TRUE); + + // ppackTLVWord(&buf, &buflen, getSettingWord(NULL, "CompanyOccupation", 0), TLV_OCUPATION, 1); // Lost In Conversion + } + + if (wParam & CIXT_EDUCATION) + { + BYTE *pBlock = NULL; + int cbBlock = 0; + int nItems = 1; + + // Studies + ppackTLVWord(&pBlock, &cbBlock, 0x64, getSettingWord(NULL, "StudyLevel", 0)); + ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "StudyInstitute", 0x6E); + ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "StudyDegree", 0x78); + ppackTLVWord(&pBlock, &cbBlock, 0x8C, getSettingWord(NULL, "StudyYear", 0)); + ppackTLVBlockItems(&buf, &buflen, 0x10E, &nItems, &pBlock, (WORD*)&cbBlock, TRUE); + } + + if (wParam & CIXT_LOCATION) + { + BYTE *pBlock = NULL; + int cbBlock = 0; + int nItems = 1; + + // Home Address + ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "Street", 0x64); + ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "City", 0x6E); + ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "State", 0x78); + ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "ZIP", 0x82); + ppackTLVDWord(&pBlock, &cbBlock, 0x8C, getSettingWord(NULL, "Country", 0)); + ppackTLVBlockItems(&buf, &buflen, 0x96, &nItems, &pBlock, (WORD*)&cbBlock, TRUE); + + nItems = 1; + // Origin Address + ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "OriginStreet", 0x64); + ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "OriginCity", 0x6E); + ppackTLVStringUtfFromDB(&pBlock, &cbBlock, "OriginState", 0x78); + ppackTLVDWord(&pBlock, &cbBlock, 0x8C, getSettingWord(NULL, "OriginCountry", 0)); + ppackTLVBlockItems(&buf, &buflen, 0xA0, &nItems, &pBlock, (WORD*)&cbBlock, TRUE); + + ppackTLVStringFromDB(&buf, &buflen, "Homepage", 0xFA); + + // Timezone + WORD wTimezone = getSettingByte(NULL, "Timezone", 0); + if ((wTimezone & 0x0080) == 0x80) wTimezone |= 0xFF00; // extend signed number + ppackTLVWord(&buf, &buflen, 0x17C, wTimezone); + } + + if (wParam & CIXT_BACKGROUND) + { + BYTE *pBlock = NULL; + int cbBlock = 0; + int nItems = 0; + + // Interests + nItems += ppackTLVWordStringUtfItemFromDB(&pBlock, &cbBlock, "Interest0Text", 0x6E, 0x64, getSettingWord(NULL, "Interest0Cat", 0)); + nItems += ppackTLVWordStringUtfItemFromDB(&pBlock, &cbBlock, "Interest1Text", 0x6E, 0x64, getSettingWord(NULL, "Interest1Cat", 0)); + nItems += ppackTLVWordStringUtfItemFromDB(&pBlock, &cbBlock, "Interest2Text", 0x6E, 0x64, getSettingWord(NULL, "Interest2Cat", 0)); + nItems += ppackTLVWordStringUtfItemFromDB(&pBlock, &cbBlock, "Interest3Text", 0x6E, 0x64, getSettingWord(NULL, "Interest3Cat", 0)); + ppackTLVBlockItems(&buf, &buflen, 0x122, &nItems, &pBlock, (WORD*)&cbBlock, FALSE); + + + /* WORD w; /// not supported anymore + + w = StringToListItemId("Past0", 0); + ppackTLVWordLNTSfromDB(&buf, &buflen, w, "Past0Text", TLV_PASTINFO); + w = StringToListItemId("Past1", 0); + ppackTLVWordLNTSfromDB(&buf, &buflen, w, "Past1Text", TLV_PASTINFO); + w = StringToListItemId("Past2", 0); + ppackTLVWordLNTSfromDB(&buf, &buflen, w, "Past2Text", TLV_PASTINFO); + + w = StringToListItemId("Affiliation0", 0); + ppackTLVWordLNTSfromDB(&buf, &buflen, w, "Affiliation0Text", TLV_AFFILATIONS); + w = StringToListItemId("Affiliation1", 0); + ppackTLVWordLNTSfromDB(&buf, &buflen, w, "Affiliation1Text", TLV_AFFILATIONS); + w = StringToListItemId("Affiliation2", 0); + ppackTLVWordLNTSfromDB(&buf, &buflen, w, "Affiliation2Text", TLV_AFFILATIONS);*/ + } + + DWORD dwCookie = icq_changeUserDirectoryInfoServ(buf, (WORD)buflen, DIRECTORYREQUEST_UPDATEOWNER); + + SAFE_FREE((void**)&buf); + + return dwCookie; + } + + return 0; // Failure +} + + +INT_PTR CIcqProto::GetAvatarCaps(WPARAM wParam, LPARAM lParam) +{ + if (wParam == AF_MAXSIZE) + { + POINT *size = (POINT*)lParam; + + if (size) + { + size->x = 64; + size->y = 64; + + return 0; + } + } + else if (wParam == AF_PROPORTION) + { + return PIP_NONE; + } + else if (wParam == AF_FORMATSUPPORTED) + { + if (lParam == PA_FORMAT_JPEG || lParam == PA_FORMAT_GIF || lParam == PA_FORMAT_XML || lParam == PA_FORMAT_BMP) + return 1; + else + return 0; + } + else if (wParam == AF_ENABLED) + { + if (m_bSsiEnabled && m_bAvatarsEnabled) + return 1; + else + return 0; + } + else if (wParam == AF_DONTNEEDDELAYS) + { + return 0; + } + else if (wParam == AF_MAXFILESIZE) + { // server accepts images of 7168 bytees, not bigger + return 7168; + } + else if (wParam == AF_DELAYAFTERFAIL) + { // do not request avatar again if server gave an error + return 1 * 60 * 60 * 1000; // one hour + } + else if (wParam == AF_FETCHALWAYS) + { // avatars can be fetched all the time (server only operation) + return 1; + } + return 0; +} + + +INT_PTR CIcqProto::GetAvatarInfo(WPARAM wParam, LPARAM lParam) +{ + PROTO_AVATAR_INFORMATIONT *pai = (PROTO_AVATAR_INFORMATIONT*)lParam; + DWORD dwUIN; + uid_str szUID; + DBVARIANT dbv = {DBVT_DELETED}; + + if (!m_bAvatarsEnabled) return GAIR_NOAVATAR; + + if (getSetting(pai->hContact, "AvatarHash", &dbv) || dbv.type != DBVT_BLOB || (dbv.cpbVal != 0x14 && dbv.cpbVal != 0x09)) + { + ICQFreeVariant(&dbv); + return GAIR_NOAVATAR; // we did not found avatar hash or hash invalid - no avatar available + } + + if (getContactUid(pai->hContact, &dwUIN, &szUID)) + { + ICQFreeVariant(&dbv); + return GAIR_NOAVATAR; // we do not support avatars for invalid contacts + } + + int dwPaFormat = getSettingByte(pai->hContact, "AvatarType", PA_FORMAT_UNKNOWN); + + if (dwPaFormat != PA_FORMAT_UNKNOWN) + { // we know the format, test file + TCHAR tszFile[MAX_PATH * 2 + 4]; + + GetFullAvatarFileName(dwUIN, szUID, dwPaFormat, tszFile, MAX_PATH * 2); + + lstrcpyn(pai->filename, tszFile, SIZEOF(pai->filename)); // Avatar API does not support unicode :-( + pai->format = dwPaFormat; + + if (!IsAvatarChanged(pai->hContact, dbv.pbVal, dbv.cpbVal)) + { // hashes are the same + if (_taccess(tszFile, 0) == 0) + { + ICQFreeVariant(&dbv); + + return GAIR_SUCCESS; // we have found the avatar file, whoala + } + } + } + + if (IsAvatarChanged(pai->hContact, dbv.pbVal, dbv.cpbVal)) + { // we didn't received the avatar before - this ensures we will not request avatar again and again + if ((wParam & GAIF_FORCE) != 0 && pai->hContact != 0) + { // request avatar data + TCHAR tszFile[MAX_PATH * 2 + 4]; + + GetAvatarFileName(dwUIN, szUID, tszFile, MAX_PATH * 2); + GetAvatarData(pai->hContact, dwUIN, szUID, dbv.pbVal, dbv.cpbVal, tszFile); + lstrcpyn(pai->filename, tszFile, SIZEOF(pai->filename)); // Avatar API does not support unicode :-( + + ICQFreeVariant(&dbv); + + return GAIR_WAITFOR; + } + } + ICQFreeVariant(&dbv); + + return GAIR_NOAVATAR; +} + + +INT_PTR CIcqProto::GetMyAvatar(WPARAM wParam, LPARAM lParam) +{ + if (!m_bAvatarsEnabled) return -2; + + if (!wParam) return -3; + + TCHAR *tszFile = GetOwnAvatarFileName(); + if (tszFile && !_taccess(tszFile, 0)) + { + _tcsncpy((TCHAR*)wParam, tszFile, (int)lParam); + SAFE_FREE(&tszFile); + return 0; + } + + SAFE_FREE(&tszFile); + return -1; +} + + +INT_PTR CIcqProto::GrantAuthorization(WPARAM wParam, LPARAM lParam) +{ + if (icqOnline() && wParam != 0) + { + DWORD dwUin; + uid_str szUid; + + if (getContactUid((HANDLE)wParam, &dwUin, &szUid)) + return 0; // Invalid contact + + // send without reason, do we need any ? + icq_sendGrantAuthServ(dwUin, szUid, NULL); + // auth granted, remove contact menu item + deleteSetting((HANDLE)wParam, "Grant"); + } + + return 0; +} + +int CIcqProto::OnIdleChanged(WPARAM wParam, LPARAM lParam) +{ + int bIdle = (lParam&IDF_ISIDLE); + int bPrivacy = (lParam&IDF_PRIVACY); + + if (bPrivacy) return 0; + + setSettingDword(NULL, "IdleTS", bIdle ? time(0) : 0); + + if (m_bTempVisListEnabled) // remove temporary visible users + sendEntireListServ(ICQ_BOS_FAMILY, ICQ_CLI_REMOVETEMPVISIBLE, BUL_TEMPVISIBLE); + + icq_setidle(bIdle ? 1 : 0); + + return 0; +} + +INT_PTR CIcqProto::RevokeAuthorization(WPARAM wParam, LPARAM lParam) +{ + if (icqOnline() && wParam != 0) + { + DWORD dwUin; + uid_str szUid; + + if (getContactUid((HANDLE)wParam, &dwUin, &szUid)) + return 0; // Invalid contact + + if (MessageBoxUtf(NULL, LPGEN("Are you sure you want to revoke user's authorization (this will remove you from his/her list on some clients) ?"), LPGEN("Confirmation"), MB_ICONQUESTION | MB_YESNO) != IDYES) + return 0; + + icq_sendRevokeAuthServ(dwUin, szUid); + } + + return 0; +} + + +INT_PTR CIcqProto::SendSms(WPARAM wParam, LPARAM lParam) +{ + if (icqOnline() && wParam && lParam) + return icq_sendSMSServ((const char *)wParam, (const char *)lParam); + + return 0; // Failure +} + +INT_PTR CIcqProto::SendYouWereAdded(WPARAM wParam, LPARAM lParam) +{ + if (lParam && icqOnline()) + { + CCSDATA* ccs = (CCSDATA*)lParam; + if (ccs->hContact) + { + DWORD dwUin, dwMyUin; + + if (getContactUid(ccs->hContact, &dwUin, NULL)) + return 1; // Invalid contact + + dwMyUin = getContactUin(NULL); + + if (dwUin) + { + icq_sendYouWereAddedServ(dwUin, dwMyUin); + return 0; // Success + } + } + } + + return 1; // Failure +} + +INT_PTR CIcqProto::SetMyAvatar(WPARAM wParam, LPARAM lParam) +{ + TCHAR* tszFile = (TCHAR*)lParam; + int iRet = -1; + + if (!m_bAvatarsEnabled || !m_bSsiEnabled) return -2; + + if (tszFile) + { // set file for avatar + int dwPaFormat = DetectAvatarFormat(tszFile); + if (dwPaFormat != PA_FORMAT_XML) + { + // if it should be image, check if it is valid + HBITMAP avt = (HBITMAP)CallService(MS_UTILS_LOADBITMAPT, 0, (WPARAM)tszFile); + if (!avt) return iRet; + DeleteObject(avt); + } + + TCHAR tszMyFile[MAX_PATH+1]; + GetFullAvatarFileName(0, NULL, dwPaFormat, tszMyFile, MAX_PATH); + // if not in our storage, copy + if (lstrcmp(tszFile, tszMyFile) && !CopyFile(tszFile, tszMyFile, FALSE)) + { + NetLog_Server("Failed to copy our avatar to local storage."); + return iRet; + } + + BYTE *hash = calcMD5HashOfFile(tszMyFile); + if (hash) + { + BYTE* ihash = (BYTE*)_alloca(0x14); + // upload hash to server + ihash[0] = 0; //unknown + ihash[1] = dwPaFormat == PA_FORMAT_XML ? AVATAR_HASH_FLASH : AVATAR_HASH_STATIC; //hash type + ihash[2] = 1; //hash status + ihash[3] = 0x10; //hash len + memcpy(ihash+4, hash, 0x10); + updateServAvatarHash(ihash, 0x14); + + if (setSettingBlob(NULL, "AvatarHash", ihash, 0x14)) + { + NetLog_Server("Failed to save avatar hash."); + } + + TCHAR tmp[MAX_PATH]; + CallService(MS_UTILS_PATHTORELATIVET, (WPARAM)tszMyFile, (LPARAM)tmp); + setSettingStringT(NULL, "AvatarFile", tmp); + + iRet = 0; + + SAFE_FREE((void**)&hash); + } + } + else + { // delete user avatar + deleteSetting(NULL, "AvatarFile"); + setSettingBlob(NULL, "AvatarHash", hashEmptyAvatar, 9); + updateServAvatarHash(hashEmptyAvatar, 9); // set blank avatar + iRet = 0; + } + + return iRet; +} + +INT_PTR CIcqProto::SetNickName(WPARAM wParam, LPARAM lParam) +{ + if (icqOnline()) + { + setSettingString(NULL, "Nick", (char*)lParam); + + return ChangeInfoEx(CIXT_BASIC, 0); + } + + return 0; // Failure +} + +INT_PTR CIcqProto::SetPassword(WPARAM wParam, LPARAM lParam) +{ + char *pwd = (char*)lParam; + int len = strlennull(pwd); + + if (len && len < PASSWORDMAXLEN) + { + strcpy(m_szPassword, pwd); + m_bRememberPwd = TRUE; + } + return 0; +} + + +// TODO: Adding needs some more work in general + +HANDLE CIcqProto::AddToListByUIN(DWORD dwUin, DWORD dwFlags) +{ + int bAdded; + HANDLE hContact = HContactFromUIN(dwUin, &bAdded); + if (hContact) + { + if (!(dwFlags & PALF_TEMPORARY) && DBGetContactSettingByte(hContact, "CList", "NotOnList", 0)) + { + setContactHidden(hContact, 0); + DBDeleteContactSetting(hContact, "CList", "NotOnList"); + } + + return hContact; // Success + } + + return NULL; // Failure +} + + +HANDLE CIcqProto::AddToListByUID(const char *szUID, DWORD dwFlags) +{ + int bAdded; + HANDLE hContact = HContactFromUID(0, szUID, &bAdded); + if (hContact) + { + if (!(dwFlags & PALF_TEMPORARY) && DBGetContactSettingByte(hContact, "CList", "NotOnList", 0)) + { + setContactHidden(hContact, 0); + DBDeleteContactSetting(hContact, "CList", "NotOnList"); + } + + return hContact; // Success + } + + return NULL; // Failure +} + + +///////////////////////////////////////////////////////////////////////////////////////// + +void CIcqProto::ICQAddRecvEvent(HANDLE hContact, WORD wType, PROTORECVEVENT* pre, DWORD cbBlob, PBYTE pBlob, DWORD flags) +{ + if (pre->flags & PREF_CREATEREAD) + flags |= DBEF_READ; + + if (pre->flags & PREF_UTF) + flags |= DBEF_UTF; + + if (hContact && DBGetContactSettingByte(hContact, "CList", "Hidden", 0)) + { + DWORD dwUin; + uid_str szUid; + + //setContactHidden(hContact, 0); + + // if the contact was hidden, add to client-list if not in server-list authed + if (!getSettingWord(hContact, DBSETTING_SERVLIST_ID, 0) || getSettingByte(hContact, "Auth", 0)) + { + getContactUid(hContact, &dwUin, &szUid); + icq_sendNewContact(dwUin, szUid); /// FIXME + } + } + + AddEvent(hContact, wType, pre->timestamp, flags, cbBlob, pBlob); +} + +INT_PTR __cdecl CIcqProto::IcqAddCapability(WPARAM wParam, LPARAM lParam) +{ + ICQ_CUSTOMCAP *icqCustomCapIn = (ICQ_CUSTOMCAP *)lParam; + ICQ_CUSTOMCAP *icqCustomCap = (ICQ_CUSTOMCAP *)malloc(sizeof(ICQ_CUSTOMCAP)); + memcpy(icqCustomCap, icqCustomCapIn, sizeof(ICQ_CUSTOMCAP)); + CustomCapList.push_back(icqCustomCap); +// MessageBoxA(NULL, ((ICQ_CUSTOMCAP *)(lstCustomCaps->items[lstCustomCaps->realCount-1]))->name, "custom cap", MB_OK); + return 0; +} + + +INT_PTR __cdecl CIcqProto::IcqCheckCapability(WPARAM wParam, LPARAM lParam) +{ + int res = 0; + DBCONTACTGETSETTING dbcgs; + DBVARIANT dbvariant; + HANDLE hContact = (HANDLE)wParam; + ICQ_CUSTOMCAP *icqCustomCap = (ICQ_CUSTOMCAP *)lParam; + dbcgs.pValue = &dbvariant; + dbcgs.szModule = m_szModuleName; + dbcgs.szSetting = "CapBuf"; + + CallService(MS_DB_CONTACT_GETSETTING, (WPARAM)hContact, (LPARAM)&dbcgs); + + if (dbvariant.type == DBVT_BLOB) + { + res = MatchCapability(dbvariant.pbVal, dbvariant.cpbVal, (const capstr*)&icqCustomCap->caps, 0x10)?1:0; // FIXME: Why icqCustomCap->caps is not capstr? + } + + CallService(MS_DB_CONTACT_FREEVARIANT,0,(LPARAM)(DBVARIANT*)&dbvariant); + + return res; +} + + + +///////////////////////////////////////////////////////////////////////////////////////// + +INT_PTR icq_getEventTextMissedMessage(WPARAM wParam, LPARAM lParam) +{ + DBEVENTGETTEXT *pEvent = (DBEVENTGETTEXT *)lParam; + + INT_PTR nRetVal = 0; + char *pszText = NULL; + + if (pEvent->dbei->cbBlob > 1) + { + switch (((WORD*)pEvent->dbei->pBlob)[0]) + { + case 0: + pszText = LPGEN("** This message was blocked by the ICQ server ** The message was invalid."); + break; + + case 1: + pszText = LPGEN("** This message was blocked by the ICQ server ** The message was too long."); + break; + + case 2: + pszText = LPGEN("** This message was blocked by the ICQ server ** The sender has flooded the server."); + break; + + case 4: + pszText = LPGEN("** This message was blocked by the ICQ server ** You are too evil."); + break; + + default: + pszText = LPGEN("** Unknown missed message event."); + break; + } + if (pEvent->datatype == DBVT_WCHAR) + { + WCHAR *pwszText; + int wchars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pszText, strlennull(pszText), NULL, 0); + + pwszText = (WCHAR*)_alloca((wchars + 1) * sizeof(WCHAR)); + pwszText[wchars] = 0; + + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pszText, strlennull(pszText), pwszText, wchars); + + nRetVal = (INT_PTR)mir_wstrdup(TranslateW(pwszText)); + } + else if (pEvent->datatype == DBVT_ASCIIZ) + nRetVal = (INT_PTR)mir_strdup(Translate(pszText)); + } + + return nRetVal; +} -- cgit v1.2.3