#include "skype_proto.h" void CSkypeProto::UpdateOwnAvatar() { uint newTS = 0; this->account->GetPropAvatarTimestamp(newTS); DWORD oldTS = this->GetSettingDword("AvatarTS"); wchar_t *path = this->GetContactAvatarFilePath(NULL); SEBinary data; this->account->GetPropAvatarImage(data); if ((newTS > oldTS) || (!newTS && data.size() > 0 && _waccess(path, 0) == -1) || (newTS && _waccess(path, 0) == -1)) //hack for avatars without timestamp { FILE* fp = _wfopen(path, L"wb"); if (fp) { fwrite(data.data(), sizeof(char), data.size(), fp); fclose(fp); this->SetSettingDword("AvatarTS", newTS); PROTO_AVATAR_INFORMATIONW pai = {0}; pai.cbSize = sizeof(pai); pai.format = PA_FORMAT_JPEG; pai.hContact = NULL; wcscpy(pai.filename, path); this->SendBroadcast(ACKTYPE_AVATAR, ACKRESULT_SUCCESS, (HANDLE)&pai, 0); } } delete path; } void CSkypeProto::UpdateOwnBirthday() { uint data; this->account->GetPropBirthday(data); TCHAR date[9]; if (data > 0) { _itot_s(data, date, 10); INT day, month, year; _stscanf(date, _T("%04d%02d%02d"), &year, &month, &day); this->SetSettingByte("BirthDay", day); this->SetSettingByte("BirthMonth", month); this->SetSettingWord("BirthYear", year); SYSTEMTIME sToday = {0}; GetLocalTime(&sToday); int nAge = sToday.wYear - year; if (sToday.wMonth < month || (sToday.wMonth == month && sToday.wDay < day)) nAge--; if (nAge) this->SetSettingWord("Age", ( WORD )nAge ); } else { this->DeleteSetting("BirthDay"); this->DeleteSetting("BirthMonth"); this->DeleteSetting("BirthYear"); this->DeleteSetting("Age"); } } void CSkypeProto::UpdateOwnCity() { SEString data; this->account->GetPropCity(data); wchar_t* city = ::mir_utf8decodeW((const char*)data); if (wcscmp(city, L"") == 0) this->DeleteSetting("City"); else this->SetSettingString("City", city); ::mir_free(city); } void CSkypeProto::UpdateOwnCountry() { // country (en, ru, etc) SEString data; char* country; this->account->GetPropCountry(data); char* isocode = ::mir_utf8decodeA((const char*)data); if (strcmp(isocode, "") == 0) { country = (char*)CallService(MS_UTILS_GETCOUNTRYBYNUMBER, 0xFFFF, 0); this->SetSettingString("Country", _A2T(country)); } else { country = (char*)CallService(MS_UTILS_GETCOUNTRYBYISOCODE, (WPARAM)isocode, 0); this->SetSettingString("Country", _A2T(country)); } ::mir_free(isocode); } void CSkypeProto::UpdateOwnEmails() { SEString data; this->account->GetPropEmails(data); wchar_t* emails = ::mir_utf8decodeW((const char*)data); if (wcscmp(emails, L"") == 0) { this->DeleteSetting("e-mail0"); this->DeleteSetting("e-mail1"); this->DeleteSetting("e-mail2"); } else { wchar_t* p = wcstok(emails, L" "); if (p == NULL) { this->SetSettingString("e-mail0", emails); } else { this->SetSettingString("e-mail0", p); p = wcstok(NULL, L" "); if (p) this->SetSettingString("e-mail1", p); p = wcstok(NULL, L" "); if (p) this->SetSettingString("e-mail2", p); } } ::mir_free(emails); } void CSkypeProto::UpdateOwnGender() { uint data; this->account->GetPropGender(data); if (data) this->SetSettingByte("Gender", (BYTE)(data == 1 ? 'M' : 'F')); else this->DeleteSetting("Gender"); } void CSkypeProto::UpdateOwnHomepage() { SEString data; this->account->GetPropHomepage(data); wchar_t* homepage = ::mir_utf8decodeW((const char*)data); if (wcscmp(homepage, L"") == 0) this->DeleteSetting("Homepage"); else this->SetSettingString("Homepage", homepage); ::mir_free(homepage); } void CSkypeProto::UpdateOwnLanguages() { // languages (en, ru, etc), space searated SEString data; this->account->GetPropLanguages(data); char* isocode = ::mir_utf8decodeA((const char*)data); if (strcmp(isocode, "") == 0) { this->DeleteSetting("Language1"); } else { for (int i = 0; i < SIZEOF(CSkypeProto::languages); i++) if ( lstrcmpiA((char*)isocode, CSkypeProto::languages[i].ISOcode) == 0) { this->SetSettingString("Language1", ::mir_a2u(CSkypeProto::languages[i].szName)); break; } } ::mir_free(isocode); } void CSkypeProto::UpdateOwnMobilePhone() { SEString data; this->account->GetPropPhoneMobile(data); wchar_t* phone = ::mir_utf8decodeW((const char*)data); if (wcscmp(phone, L"") == 0) this->DeleteSetting("Cellular"); else this->SetSettingString("Cellular", phone); ::mir_free(phone); } void CSkypeProto::UpdateOwnNickName() { SEString data; this->account->GetPropFullname(data); wchar_t* nick = ::mir_utf8decodeW((const char*)data); this->SetSettingString("Nick", nick); ::mir_free(nick); } void CSkypeProto::UpdateOwnPhone() { SEString data; this->account->GetPropPhoneHome(data); wchar_t* phone = ::mir_utf8decodeW((const char*)data); if (wcscmp(phone, L"") == 0) this->DeleteSetting("Phone"); else this->SetSettingString("Phone", phone); ::mir_free(phone); } void CSkypeProto::UpdateOwnOfficePhone() { SEString data; this->account->GetPropPhoneOffice(data); wchar_t* phone = ::mir_utf8decodeW((const char*)data); if (wcscmp(phone, L"") == 0) this->DeleteSetting("CompanyPhone"); else this->SetSettingString("CompanyPhone", phone); ::mir_free(phone); } void CSkypeProto::UpdateOwnState() { SEString data; this->account->GetPropProvince(data); wchar_t* state = ::mir_utf8decodeW((const char*)data); if (wcscmp(state, L"") == 0) this->DeleteSetting("State"); else this->SetSettingString("State", state); ::mir_free(state); } void CSkypeProto::UpdateOwnStatusMessage() { uint newTS = 0; this->account->GetPropMoodTimestamp(newTS); DWORD oldTS = this->GetSettingDword("XStatusTS"); if (newTS > oldTS) { SEString data; this->account->GetPropMoodText(data); wchar_t* status = ::mir_utf8decodeW((const char*)data); if (wcscmp(status, L"") == 0) this->DeleteSetting("XStatusMsg"); else this->SetSettingString("XStatusMsg", status); ::mir_free(status); this->SetSettingDword("XStatusTS", newTS); } } void CSkypeProto::UpdateOwnTimezone() { uint data; this->account->GetPropTimezone(data); if (data > 0) { uint diffmin = (data - 24*3600) / 60; wchar_t sign[2]; if (diffmin < 0) ::wcscpy(sign, L"-"); else ::wcscpy(sign, L"+"); uint hours = ::abs((int)(diffmin / 60)); uint mins = ::abs((int)(diffmin % 60)); wchar_t timeshift[7]; ::mir_sntprintf(timeshift, SIZEOF(timeshift), _T("%s%d:%02d"), sign, hours, mins); wchar_t *szMin = wcschr(timeshift, ':'); int nTz = ::_wtoi(timeshift) * -2; nTz += (nTz < 0 ? -1 : 1) * (szMin ? _ttoi( szMin + 1 ) / 30 : 0); TIME_ZONE_INFORMATION tzinfo; if (::GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_DAYLIGHT) nTz -= tzinfo.DaylightBias / 30; this->SetSettingByte("Timezone", (signed char)nTz); } else this->DeleteSetting("TimeZone"); } void CSkypeProto::UpdateOwnAbout() { SEString data; this->account->GetPropAbout(data); wchar_t* about = ::mir_utf8decodeW((const char*)data); if (wcscmp(about, L"") == 0) this->DeleteSetting("About"); else this->SetSettingString("About", about); ::mir_free(about); } void CSkypeProto::UpdateOwnProfile() { uint newTS = 0; this->account->GetPropProfileTimestamp(newTS); DWORD oldTS = this->GetSettingDword("ProfileTS"); if (newTS > oldTS) { this->UpdateOwnAvatar(); this->UpdateOwnBirthday(); this->UpdateOwnCity(); this->UpdateOwnCountry(); this->UpdateOwnEmails(); this->UpdateOwnGender(); this->UpdateOwnHomepage(); this->UpdateOwnLanguages(); this->UpdateOwnMobilePhone(); this->UpdateOwnNickName(); this->UpdateOwnPhone(); this->UpdateOwnOfficePhone(); this->UpdateOwnState(); this->UpdateOwnStatusMessage(); this->UpdateOwnTimezone(); this->UpdateOwnAbout(); this->SetSettingDword("ProfileTS", newTS); } } void CSkypeProto::OnProfileChanged(int prop) { switch(prop) { case CAccount::P_AVATAR_IMAGE: case CAccount::P_AVATAR_TIMESTAMP: this->UpdateOwnAvatar(); break; case CAccount::P_BIRTHDAY: this->UpdateOwnBirthday(); break; case CAccount::P_CITY: this->UpdateOwnCity(); break; case CAccount::P_COUNTRY: this->UpdateOwnCountry(); break; case CAccount::P_EMAILS: this->UpdateOwnEmails(); break; case CAccount::P_GENDER: this->UpdateOwnGender(); break; case CAccount::P_HOMEPAGE: this->UpdateOwnHomepage(); break; case CAccount::P_LANGUAGES: this->UpdateOwnLanguages(); break; case CAccount::P_MOOD_TEXT: case CAccount::P_MOOD_TIMESTAMP: this->UpdateOwnStatusMessage(); break; case CAccount::P_PHONE_HOME: this->UpdateOwnPhone(); break; case CAccount::P_PHONE_MOBILE: this->UpdateOwnMobilePhone(); break; case CAccount::P_PHONE_OFFICE: this->UpdateOwnOfficePhone(); break; case CAccount::P_PROFILE_TIMESTAMP: this->UpdateOwnProfile(); break; case CAccount::P_PROVINCE: this->UpdateOwnState(); break; case CAccount::P_TIMEZONE: this->UpdateOwnTimezone(); break; case CAccount::P_FULLNAME: this->UpdateOwnNickName(); break; case CAccount::P_ABOUT: this->UpdateOwnAbout(); break; } } void __cdecl CSkypeProto::LoadOwnInfo(void*) { this->UpdateOwnProfile(); }