diff options
Diffstat (limited to 'protocols/Skype/src')
-rw-r--r-- | protocols/Skype/src/skype_contacts.cpp | 672 | ||||
-rw-r--r-- | protocols/Skype/src/skype_database.cpp | 55 | ||||
-rw-r--r-- | protocols/Skype/src/skype_events.cpp | 7 | ||||
-rw-r--r-- | protocols/Skype/src/skype_proto.cpp | 101 | ||||
-rw-r--r-- | protocols/Skype/src/skype_proto.h | 54 | ||||
-rw-r--r-- | protocols/Skype/src/skype_settings.cpp | 10 | ||||
-rw-r--r-- | protocols/Skype/src/skype_subclassing.cpp | 42 | ||||
-rw-r--r-- | protocols/Skype/src/skype_subclassing.h | 31 |
8 files changed, 779 insertions, 193 deletions
diff --git a/protocols/Skype/src/skype_contacts.cpp b/protocols/Skype/src/skype_contacts.cpp index fd1d6afe1d..55fdb90b3d 100644 --- a/protocols/Skype/src/skype_contacts.cpp +++ b/protocols/Skype/src/skype_contacts.cpp @@ -1,27 +1,449 @@ #include "skype_proto.h"
-void CSkypeProto::OnContactChanged(CContact* contact, int prop)
+void CSkypeProto::UpdateContactAboutText(HANDLE hContact, CContact::Ref contact)
{
- if (prop == CContact::P_AVAILABILITY)
+ SEString data;
+ contact->GetPropAbout(data);
+ wchar_t* aboutText = ::mir_utf8decodeW((const char*)data);
+ if (wcscmp(aboutText, L"") == 0)
+ this->DeleteSetting(hContact, "About");
+ else
+ this->SetSettingString(hContact, "About", aboutText);
+ ::mir_free(aboutText);
+}
+
+void CSkypeProto::UpdateContactAuthState(HANDLE hContact, CContact::Ref contact)
+{
+ uint newTS = 0;
+ contact->GetPropAuthreqTimestamp(newTS);
+ DWORD oldTS = this->GetSettingDword(hContact, "AuthTS");
+ if (newTS > oldTS)
+ {
+ CContact::AVAILABILITY data;
+ contact->GetPropAvailability(data);
+ this->SetSettingWord(hContact, SKYPE_SETTINGS_STATUS, this->SkypeToMirandaStatus(data));
+
+ if (data == CContact::PENDINGAUTH)
+ this->SetSettingWord(hContact, "Auth", 1);
+ else
+ this->DeleteSetting(hContact, "Auth");
+
+ this->SetSettingDword(hContact, "AuthTS", newTS);
+ }
+}
+
+void CSkypeProto::UpdateContactAvatar(HANDLE hContact, CContact::Ref contact)
+{
+ uint newTS = 0;
+ contact->GetPropAvatarTimestamp(newTS);
+ DWORD oldTS = this->GetSettingDword(hContact, "AvatarTS");
+ if (newTS > oldTS)
+ {
+ SEBinary data;
+ contact->GetPropAvatarImage(data);
+
+ if (data.size() > 0)
+ {
+ wchar_t* path = this->GetAvatarFilePath(this->GetSettingString(hContact, "SkypeName"));
+ FILE* fp = _wfopen(path, L"w");
+ if (fp)
+ {
+ for (uint i = 0; i < data.size(); i++)
+ {
+ if (i)
+ fputc(',', fp);
+ fputc('\'', fp);
+ switch(data[i])
+ {
+ case '\n':
+ fputc('\\', fp);
+ fputc('n', fp);
+ break;
+
+ default:
+ fputc(data[i], fp);
+ }
+ }
+ CloseHandle(fp);
+ }
+ }
+ // todo: need to register avatar to contact
+ this->SetSettingDword(hContact, "AvatarTS", newTS);
+ }
+}
+
+void CSkypeProto::UpdateContactBirthday(HANDLE hContact, CContact::Ref contact)
+{
+ uint data;
+ contact->GetPropBirthday(data);
+ if (data > 0)
+ {
+ struct tm* ptm;
+ time_t timeGMT = (time_t)data;
+ ptm = gmtime(&timeGMT);
+ this->SetSettingByte(hContact, "BirthDay", ptm->tm_mday);
+ this->SetSettingByte(hContact, "BirthMonth", ptm->tm_mon);
+ // todo: fix stupid year constant
+ this->SetSettingWord(hContact, "BirthYear", ptm->tm_year + 1917);
+ }
+ else
+ {
+ this->DeleteSetting(hContact, "BirthDay");
+ this->DeleteSetting(hContact, "BirthMonth");
+ this->DeleteSetting(hContact, "BirthYear");
+ }
+}
+
+void CSkypeProto::UpdateContactCity(HANDLE hContact, CContact::Ref contact)
+{
+ SEString data;
+ contact->GetPropCity(data);
+ wchar_t* city = ::mir_a2u((const char*)data);
+ if (wcscmp(city, L"") == 0)
+ this->DeleteSetting(hContact, "City");
+ else
+ this->SetSettingString(hContact, "City", city);
+ ::mir_free(city);
+}
+
+void CSkypeProto::UpdateContactCountry(HANDLE hContact, CContact::Ref contact)
+{
+ // country (en, ru, etc)
+ SEString data;
+ contact->GetPropCountry(data);
+ // todo: write me
+ //BYTE countryId = this->GetCountryIdByName((const char*)sData);
+ //this->SetSettingByte(hContact, "Country", countryId);
+}
+
+void CSkypeProto::UpdateContactEmails(HANDLE hContact, CContact::Ref contact)
+{
+ SEString data;
+ contact->GetPropEmails(data);
+ wchar_t* emails = ::mir_a2u((const char*)data);
+ if (wcscmp(emails, L"") == 0)
+ {
+ this->DeleteSetting(hContact, "e-mail0");
+ this->DeleteSetting(hContact, "e-mail1");
+ this->DeleteSetting(hContact, "e-mail2");
+ }
+ else
+ {
+ wchar_t* p = wcstok(emails, L" ");
+ if (p == NULL)
+ {
+ this->SetSettingString(hContact, "e-mail0", emails);
+ }
+ else
+ {
+ this->SetSettingString(hContact, "e-mail0", p);
+ p = wcstok(NULL, L" ");
+ if (p) this->SetSettingString(hContact, "e-mail1", p);
+ p = wcstok(NULL, L" ");
+ if (p) this->SetSettingString(hContact, "e-mail2", p);
+ }
+ }
+ ::mir_free(emails);
+}
+
+void CSkypeProto::UpdateContactGender(HANDLE hContact, CContact::Ref contact)
+{
+ uint data;
+ contact->GetPropGender(data);
+ if (data)
+ this->SetSettingByte(hContact, "Gender", (BYTE)(data == 1 ? 'M' : 'F'));
+ else
+ this->DeleteSetting(hContact, "Gender");
+}
+
+void CSkypeProto::UpdateContactHomepage(HANDLE hContact, CContact::Ref contact)
+{
+ SEString data;
+ contact->GetPropHomepage(data);
+ wchar_t* homepage = ::mir_a2u((const char*)data);
+ if (wcscmp(homepage, L"") == 0)
+ this->DeleteSetting(hContact, "Homepage");
+ else
+ this->SetSettingString(hContact, "Homepage", homepage);
+ ::mir_free(homepage);
+}
+
+void CSkypeProto::UpdateContactLanguages(HANDLE hContact, CContact::Ref contact)
+{
+ // sanguages (en, ru, etc), space searated
+ SEString data;
+ contact->GetPropLanguages(data);
+ // todo: write me
+}
+
+void CSkypeProto::UpdateContactMobilePhone(HANDLE hContact, CContact::Ref contact)
+{
+ SEString data;
+ contact->GetPropPhoneMobile(data);
+ wchar_t* phone = ::mir_a2u((const char*)data);
+ if (wcscmp(phone, L"") == 0)
+ this->DeleteSetting(hContact, "Cellular");
+ else
+ this->SetSettingString(hContact, "Cellular", phone);
+ ::mir_free(phone);
+}
+
+void CSkypeProto::UpdateContactPhone(HANDLE hContact, CContact::Ref contact)
+{
+ SEString data;
+ contact->GetPropPhoneHome(data);
+ wchar_t* phone = ::mir_a2u((const char*)data);
+ if (wcscmp(phone, L"") == 0)
+ this->DeleteSetting(hContact, "Phone");
+ else
+ this->SetSettingString(hContact, "Phone", phone);
+ ::mir_free(phone);
+}
+
+void CSkypeProto::UpdateContactOfficePhone(HANDLE hContact, CContact::Ref contact)
+{
+ SEString data;
+ contact->GetPropPhoneOffice(data);
+ wchar_t* phone = ::mir_a2u((const char*)data);
+ if (wcscmp(phone, L"") == 0)
+ this->DeleteSetting(hContact, "CompanyPhone");
+ else
+ this->SetSettingString(hContact, "CompanyPhone", phone);
+ ::mir_free(phone);
+}
+
+void CSkypeProto::UpdateContactState(HANDLE hContact, CContact::Ref contact)
+{
+ SEString data;
+ contact->GetPropProvince(data);
+ wchar_t* state = ::mir_a2u((const char*)data);
+ if (wcscmp(state, L"") == 0)
+ this->DeleteSetting(hContact, "State");
+ else
+ this->SetSettingString(hContact, "State", state);
+ ::mir_free(state);
+}
+
+void CSkypeProto::UpdateContactStatus(HANDLE hContact, CContact::Ref contact)
+{
+ CContact::AVAILABILITY availability;
+ contact->GetPropAvailability(availability);
+ this->SetSettingWord(hContact, SKYPE_SETTINGS_STATUS, this->SkypeToMirandaStatus(availability));
+}
+
+void CSkypeProto::UpdateContactStatusMessage(HANDLE hContact, CContact::Ref contact)
+{
+ uint newTS = 0;
+ contact->GetPropMoodTimestamp(newTS);
+ DWORD oldTS = this->GetSettingDword(hContact, "XStatusTS");
+ if (newTS > oldTS)
{
SEString data;
+ contact->GetPropMoodText(data);
+ wchar_t* status = ::mir_utf8decodeW((const char*)data);
+ if (wcscmp(status, L"") == 0)
+ this->DeleteSetting(hContact, "XStatusMsg");
+ else
+ this->SetSettingString(hContact, "XStatusMsg", status);
+ ::mir_free(status);
+ this->SetSettingDword(hContact, "XStatusTS", newTS);
+ }
+}
- contact->GetPropSkypename(data);
- wchar_t* skypeName = ::mir_a2u((const char*)data);
+void CSkypeProto::UpdateContactTimezone(HANDLE hContact, CContact::Ref contact)
+{
+ uint data;
+ contact->GetPropTimezone(data);
+ // todo: check me
+ if (data > 0)
+ this->SetSettingByte(hContact, "TimeZone", (data - 24*3600) / 3600);
+ else
+ this->DeleteSetting(hContact, "TimeZone");
+}
+
+void CSkypeProto::UpdateContactProfile(HANDLE hContact, CContact::Ref contact)
+{
+ uint newTS = 0;
+ contact->GetPropProfileTimestamp(newTS);
+ DWORD oldTS = this->GetSettingDword(hContact, "ProfileTS");
+ if (newTS > oldTS)
+ {
+ this->UpdateContactAboutText(hContact, contact);
+ this->UpdateContactBirthday(hContact, contact);
+ this->UpdateContactCity(hContact, contact);
+ this->UpdateContactCountry(hContact, contact);
+ this->UpdateContactEmails(hContact, contact);
+ this->UpdateContactGender(hContact, contact);
+ this->UpdateContactHomepage(hContact, contact);
+ this->UpdateContactLanguages(hContact, contact);
+ this->UpdateContactMobilePhone(hContact, contact);
+ this->UpdateContactPhone(hContact, contact);
+ this->UpdateContactOfficePhone(hContact, contact);
+ this->UpdateContactState(hContact, contact);
+ this->UpdateContactTimezone(hContact, contact);
+
+ this->SetSettingDword(hContact, "ProfileTS", newTS);
+ }
+}
+
+void CSkypeProto::OnContactChanged(CContact::Ref contact, int prop)
+{
+ SEString data;
+ contact->GetPropSkypename(data);
+ wchar_t* sid = ::mir_a2u((const char*)data);
+ HANDLE hContact = this->GetContactBySid(sid);
- HANDLE hContact = this->GetContactBySkypeName(skypeName);
- if (hContact)
+ if (hContact)
+ {
+ switch(prop)
{
- CContact::AVAILABILITY availability;
- contact->GetPropAvailability(availability);
- this->SetSettingWord(hContact, SKYPE_SETTINGS_STATUS, this->SkypeToMirandaStatus(availability));
-
- if (availability == CContact::PENDINGAUTH)
- this->SetSettingWord(hContact, "Auth", 1);
- else
- this->DeleteSetting(hContact, "Auth");
+ case CContact::P_ABOUT:
+ this->UpdateContactAboutText(hContact, contact);
+ break;
+ case CContact::P_AUTHREQ_TIMESTAMP:
+ {
+ uint newTS = 0;
+ contact->GetPropAuthreqTimestamp(newTS);
+ DWORD oldTS = this->GetSettingDword(hContact, "AuthTS");
+ if (newTS > oldTS)
+ {
+ char* sid = ::mir_utf8decodeA((const char*)data);
+
+ contact->GetPropDisplayname(data);
+ char* nick = ::mir_utf8decodeA((const char*)data);
+
+ contact->GetPropReceivedAuthrequest(data);
+ char* reason = ::mir_utf8decodeA((const char*)data);
+
+ //todo: add first/last name
+ this->RaiseAuthRequestEvent(newTS, sid, nick, "", "", reason);
+ }
+ }
+ break;
+ case CContact::P_AUTHREQUEST_COUNT:
+ // todo: all authrequests after first should be catch here
+ this->UpdateContactAuthState(hContact, contact);
+ break;
+ case CContact::P_AVAILABILITY:
+ this->UpdateContactStatus(hContact, contact);
+ break;
+ case CContact::P_AVATAR_IMAGE:
+ case CContact::P_AVATAR_TIMESTAMP:
+ this->UpdateContactAvatar(hContact, contact);
+ break;
+ case CContact::P_BIRTHDAY:
+ this->UpdateContactBirthday(hContact, contact);
+ break;
+ case CContact::P_CITY:
+ this->UpdateContactCity(hContact, contact);
+ break;
+ case CContact::P_COUNTRY:
+ this->UpdateContactCountry(hContact, contact);
+ break;
+ case CContact::P_EMAILS:
+ this->UpdateContactEmails(hContact, contact);
+ break;
+ case CContact::P_GENDER:
+ this->UpdateContactGender(hContact, contact);
+ break;
+ case CContact::P_HOMEPAGE:
+ this->UpdateContactHomepage(hContact, contact);
+ break;
+ case CContact::P_LANGUAGES:
+ this->UpdateContactLanguages(hContact, contact);
+ break;
+ case CContact::P_MOOD_TEXT:
+ case CContact::P_MOOD_TIMESTAMP:
+ this->UpdateContactStatusMessage(hContact, contact);
+ break;
+ case CContact::P_PHONE_HOME:
+ this->UpdateContactPhone(hContact, contact);
+ break;
+ case CContact::P_PHONE_MOBILE:
+ this->UpdateContactMobilePhone(hContact, contact);
+ break;
+ case CContact::P_PHONE_OFFICE:
+ this->UpdateContactOfficePhone(hContact, contact);
+ break;
+ case CContact::P_PROFILE_TIMESTAMP:
+ this->UpdateContactProfile(hContact, contact);
+ break;
+ case CContact::P_PROVINCE:
+ this->UpdateContactState(hContact, contact);
+ break;
+ case CContact::P_TIMEZONE:
+ this->UpdateContactTimezone(hContact, contact);
+ break;
}
}
+ //else
+ //{
+ // switch(prop)
+ // {
+ // case CContact::P_RECEIVED_AUTHREQUEST:
+ // contact->GetPropDisplayname(data);
+ // wchar_t* displayName = ::mir_a2u((const char*)data);
+
+ // CCSDATA ccs = {0};
+ // ccs.szProtoService = PSR_AUTH;
+ // ccs.hContact = this->AddContactBySkypeName(skypeName, displayName, PALF_TEMPORARY);
+ // //pre.szMessage = (LPSTR)btBuff;
+ // //CreateBlobFromContact(ccs.hContact, lpwszMessage, dwMessageSize, btBuff, SIZEOF(btBuff), (size_t*)&pre.lParam);
+ // CallService(MS_PROTO_CHAINRECV, 0, (LPARAM)&ccs);
+ // break;
+ // }
+ //}
+
+ //if (prop == CContact::P_AVAILABILITY)
+ //{
+ // SEString data;
+
+ // contact->GetPropSkypename(data);
+ // wchar_t* skypeName = ::mir_a2u((const char*)data);
+
+ // HANDLE hContact = this->GetContactBySkypeName(skypeName);
+ // if (hContact)
+ // {
+ // CContact::AVAILABILITY availability;
+ // contact->GetPropAvailability(availability);
+ // this->SetSettingWord(hContact, SKYPE_SETTINGS_STATUS, this->SkypeToMirandaStatus(availability));
+
+ // if (availability == CContact::PENDINGAUTH)
+ // this->SetSettingWord(hContact, "Auth", 1);
+ // else
+ // this->DeleteSetting(hContact, "Auth");
+ // }
+ //}
+}
+
+void CSkypeProto::OnContactListChanged(const ContactRef& contact)
+{
+ CContactGroup::TYPE type;
+ this->contactList->GetPropType(type);
+ //switch (type)
+ //{
+ //case CContactGroup::ALL_KNOWN_CONTACTS:
+ // if ( !this->contactList->Contains(contact))
+ // {
+ // SEString data;
+
+ // contact->GetPropSkypename(data);
+ // wchar_t* sid = ::mir_utf8decodeW((const char*)data);
+ //
+ // contact->GetPropDisplayname(data);
+ // wchar_t* nick = ::mir_utf8decodeW((const char*)data);
+ //
+ // contact->GetPropReceivedAuthrequest(data);
+ // wchar_t* reason = ::mir_utf8decodeW((const char*)data);
+
+ // uint newTS = 0;
+ // contact->GetPropAuthreqTimestamp(newTS);
+ //
+ // //todo: add first/last name
+ // this->RaiseAuthRequestEvent(newTS, sid, nick, L"", L"", reason);
+ // }
+ // break;
+ //}
}
bool CSkypeProto::IsProtoContact(HANDLE hContact)
@@ -29,17 +451,14 @@ bool CSkypeProto::IsProtoContact(HANDLE hContact) return ::CallService(MS_PROTO_ISPROTOONCONTACT, (WPARAM)hContact, (LPARAM)this->m_szModuleName) < 0;
}
-HANDLE CSkypeProto::GetContactBySkypeName(wchar_t* skypeName)
+HANDLE CSkypeProto::GetContactBySid(const wchar_t* sid)
{
HANDLE hContact = (HANDLE)::CallService(MS_DB_CONTACT_FINDFIRST, 0, 0);
while (hContact)
{
if (this->IsProtoContact(hContact))
{
- wchar_t* data = this->GetSettingString(hContact, "SkypeName", L"");
- bool result = ::wcscmp(skypeName, data) == 0;
- mir_free(data);
- if (result)
+ if (::wcscmp(sid, this->GetSettingString(hContact, "sid", L"")) == 0)
return hContact;
}
@@ -49,16 +468,36 @@ HANDLE CSkypeProto::GetContactBySkypeName(wchar_t* skypeName) return 0;
}
-HANDLE CSkypeProto::AddContactBySkypeName(wchar_t* skypeName, wchar_t* displayName, DWORD flags)
+HANDLE CSkypeProto::GetContactFromAuthEvent(HANDLE hEvent)
+{
+ DWORD body[3];
+ DBEVENTINFO dbei = { sizeof(DBEVENTINFO) };
+ dbei.cbBlob = sizeof(DWORD) * 2;
+ dbei.pBlob = (PBYTE)&body;
+
+ if (::CallService(MS_DB_EVENT_GET, (WPARAM)hEvent, (LPARAM)&dbei))
+ return INVALID_HANDLE_VALUE;
+
+ if (dbei.eventType != EVENTTYPE_AUTHREQUEST)
+ return INVALID_HANDLE_VALUE;
+
+ if (strcmp(dbei.szModule, this->m_szModuleName) != 0)
+ return INVALID_HANDLE_VALUE;
+
+ return ::DbGetAuthEventContact(&dbei);
+}
+
+HANDLE CSkypeProto::AddContactBySid(const wchar_t* sid, const wchar_t* nick, DWORD flags)
{
- HANDLE hContact = this->GetContactBySkypeName(skypeName);
+ HANDLE hContact = this->GetContactBySid(sid);
if ( !hContact)
{
hContact = (HANDLE)::CallService(MS_DB_CONTACT_ADD, 0, 0);
::CallService(MS_PROTO_ADDTOCONTACT, (WPARAM)hContact, (LPARAM)this->m_szModuleName);
- this->SetSettingString(hContact, "SkypeName", skypeName);
- this->SetSettingString(hContact, "Nick", displayName);
+ this->SetSettingString(hContact, "sid", sid);
+
+ this->SetSettingString(hContact, "Nick", nick);
//::DBWriteContactSettingWString(hContact, "CList", "MyHandle", displayName);
if (flags & PALF_TEMPORARY)
@@ -69,7 +508,7 @@ HANDLE CSkypeProto::AddContactBySkypeName(wchar_t* skypeName, wchar_t* displayNa }
else
{
- if (!(flags & PALF_TEMPORARY))
+ if ( !(flags & PALF_TEMPORARY))
::DBWriteContactSettingByte(hContact, "CList", "NotOnList", 1);
}
@@ -101,6 +540,27 @@ int CSkypeProto::SkypeToMirandaStatus(CContact::AVAILABILITY availability) return status;
}
+void CSkypeProto::RemoveContact(HANDLE hContact)
+{
+ if (this->IsOnline() && hContact)
+ {
+ //bool canDelete = false;
+ CContact::Ref contact;
+ SEString sid(::mir_u2a(this->GetSettingString(hContact, "sid")));
+ g_skype->GetContact(sid, contact);
+ contact->SetBuddyStatus(CContact::BLOCKED_BY_ME);
+
+ //this->contactList->CanRemoveContact(canDelete);
+ //if (canDelete)
+ {
+ contact->SetBuddyStatus(false/*CContact::BLOCKED_BY_ME*/);
+ this->contactList->ContactList.remove_val(contact);
+ this->contactList->RemoveContact(contact);
+ this->contactList.fetch();
+ }
+ }
+}
+
CContact::AVAILABILITY CSkypeProto::MirandaToSkypeStatus(int status)
{
CContact::AVAILABILITY availability = CContact::UNKNOWN;
@@ -127,151 +587,47 @@ CContact::AVAILABILITY CSkypeProto::MirandaToSkypeStatus(int status) return availability;
}
-void CSkypeProto::LoadContactInfo(HANDLE hContact, CContact::Ref contact)
-{
- CContact::AVAILABILITY availability;
- contact->GetPropAvailability(availability);
- this->SetSettingWord(hContact, SKYPE_SETTINGS_STATUS, this->SkypeToMirandaStatus(availability));
-
- if (availability == CContact::PENDINGAUTH)
- this->SetSettingWord(hContact, "Auth", 1);
- else
- this->DeleteSetting(hContact, "Auth");
-
- uint newTS = 0;
- DWORD oldTS = 0;
-
- // profile info
- contact->GetPropProfileTimestamp(newTS);
- oldTS = this->GetSettingDword(hContact, "ProfileUpdateTS");
- //if (newTS > oldTS)
- {
- uint uData;
- SEString sData;
- // birth date
- contact->GetPropBirthday(uData);
- if (uData > 0)
- {
- struct tm* ptm;
- time_t timeGMT = (time_t)uData;
- ptm = gmtime(&timeGMT);
- this->SetSettingByte(hContact, "BirthDay", ptm->tm_mday);
- this->SetSettingByte(hContact, "BirthMonth", ptm->tm_mon);
- this->SetSettingWord(hContact, "BirthYear", ptm->tm_year + 1917);
- }
- // gender
- contact->GetPropGender(uData);
- this->SetSettingByte(hContact, "Gender", (BYTE)(uData ? 'M' : 'F'));
- // timezone
- contact->GetPropTimezone(uData);
- if (uData > 0)
- this->SetSettingByte(hContact, "TimeZone", uData);
- else
- this->DeleteSetting(hContact, "TimeZone");
- // language
- contact->GetPropLanguages(sData);
- // country (en, ru, etc)
- contact->GetPropCountry(sData);
- BYTE countryId = this->GetCountryIdByName((const char*)sData);
- this->SetSettingByte(hContact, "Country", countryId);
- // state
- contact->GetPropProvince(sData);
- this->SetSettingString(hContact, "State", ::mir_a2u((const char*)sData));
- // city
- contact->GetPropCity(sData);
- this->SetSettingString(hContact, "City", ::mir_a2u((const char*)sData));
- // home phone - contact->GetPropPhoneHome(sData); - this->SetSettingString(hContact, "Phone", ::mir_a2u((const char*)sData)); - // office phone - contact->GetPropPhoneOffice(sData); - this->SetSettingString(hContact, "CompanyPhone", ::mir_a2u((const char*)sData)); - // mobile phone - contact->GetPropPhoneMobile(sData);
- this->SetSettingString(hContact, "Cellular", ::mir_a2u((const char*)sData));
- // e-mail - contact->GetPropEmails(sData); - this->SetSettingString(hContact, "e-mail", ::mir_a2u((const char*)sData)); - // homepage - contact->GetPropHomepage(sData); - this->SetSettingString(hContact, "Homepage", ::mir_a2u((const char*)sData)); - // about - contact->GetPropAbout(sData);
- this->SetSettingString(hContact, "About", ::mir_a2u((const char*)sData));
- // profile update ts
- this->SetSettingDword(hContact, "ProfileUpdateTS", newTS);
- }
-
- // mood text
- contact->GetPropProfileTimestamp(newTS);
- oldTS = this->GetSettingDword(hContact, "XStatusTS");
- if (newTS > oldTS)
- {
- SEString status;
- contact->GetPropAbout(status);
- this->SetSettingString(hContact, "XStatusMsg", ::mir_a2u((const char*)status));
- // mood text update ts
- this->SetSettingDword(hContact, "XStatusTS", newTS);
- }
-
- // avatar
- contact->GetPropProfileTimestamp(newTS);
- oldTS = this->GetSettingDword(hContact, "AvatarTS");
- if (newTS > oldTS)
- {
- SEBinary avatar;
- contact->GetPropAvatarImage(avatar);
-
- if (avatar.size() > 0)
- {
- FILE* fp = _wfopen(this->GetAvatarFilePath(this->GetSettingString(hContact, "SkypeName")), L"w");
- for (int i = 0; i < avatar.size(); i++)
- {
- if (i)
- fputc(',', fp);
- fputc('\'', fp);
- switch(avatar[i])
- {
- case '\n':
- fputc('\\', fp);
- fputc('n', fp);
- break;
-
- default:
- fputc(avatar[i], fp);
- }
- }
- CloseHandle(fp);
- }
- // todo: need to register avatar to contact
- //avatar update ts
- this->SetSettingDword(hContact, "AvatarTS", newTS);
- }
-}
-
void __cdecl CSkypeProto::LoadContactList(void*)
{
- g_skype->GetHardwiredContactGroup(CContactGroup::ALL_KNOWN_CONTACTS, this->contactGroup);
-
- this->contactGroup->GetContacts(this->contactGroup->ContactList);
- Sid::fetch(this->contactGroup->ContactList);
-
- for (unsigned int i = 0; i < this->contactGroup->ContactList.size(); i++)
+ g_skype->GetHardwiredContactGroup(CContactGroup::ALL_KNOWN_CONTACTS, this->contactList);
+ this->contactList.fetch();
+ this->contactList->SetOnContactListChangedCallback(
+ (CContactGroup::OnContactListChanged)&CSkypeProto::OnContactListChanged,
+ this);
+ this->contactList->GetContacts(this->contactList->ContactList);
+ Sid::fetch(this->contactList->ContactList);
+
+ for (unsigned int i = 0; i < this->contactList->ContactList.size(); i++)
{
- CContact::Ref contact = this->contactGroup->ContactList[i];
- contact->SetOnContactChangeCallback((OnContactChangeFunc)&CSkypeProto::OnContactChanged, this);
+ CContact::Ref contact = this->contactList->ContactList[i];
+ contact->SetOnContactChangedCallback(
+ (CContact::OnContactChanged)&CSkypeProto::OnContactChanged,
+ this);
SEString data;
contact->GetPropSkypename(data);
- wchar_t* skypeName = ::mir_a2u((const char*)data);
+ wchar_t* sid = ::mir_utf8decodeW((const char*)data);
contact->GetPropDisplayname(data);
- wchar_t* displayName = :: mir_utf8decodeW((const char*)data);
+ wchar_t* nick = ::mir_utf8decodeW((const char*)data);
+
+ contact->GetPropFullname(data);
+ wchar_t* name = ::mir_utf8decodeW((const char*)data);
+
+ DWORD flags = 0;
+ CContact::AVAILABILITY availability;
+ contact->GetPropAvailability(availability);
+ if (availability == CContact::PENDINGAUTH)
+ flags = PALF_TEMPORARY;
- HANDLE hContact = this->AddContactBySkypeName(skypeName, displayName, 0);
+ HANDLE hContact = this->AddContactBySid(sid, nick, flags);
- this->LoadContactInfo(hContact, contact);
+ this->UpdateContactAuthState(hContact, contact);
+ this->UpdateContactAvatar(hContact, contact);
+ this->UpdateContactProfile(hContact, contact);
+ this->UpdateContactStatus(hContact, contact);
+ this->UpdateContactStatusMessage(hContact, contact);
}
}
diff --git a/protocols/Skype/src/skype_database.cpp b/protocols/Skype/src/skype_database.cpp new file mode 100644 index 0000000000..b22c632be0 --- /dev/null +++ b/protocols/Skype/src/skype_database.cpp @@ -0,0 +1,55 @@ +#include "skype_proto.h"
+
+HANDLE CSkypeProto::AddDataBaseEvent(HANDLE hContact, WORD type, DWORD time, DWORD flags, DWORD cbBlob, PBYTE pBlob)
+{
+ DBEVENTINFO dbei = {0};
+
+ dbei.cbSize = sizeof(dbei);
+ dbei.szModule = this->m_szModuleName;
+ dbei.timestamp = time;
+ dbei.flags = flags;
+ dbei.eventType = type;
+ dbei.cbBlob = cbBlob;
+ dbei.pBlob = pBlob;
+
+ return (HANDLE)CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei);
+}
+
+void CSkypeProto::RaiseAuthRequestEvent(
+ DWORD timestamp,
+ const char* sid,
+ const char* nick,
+ const char* firstName,
+ const char* lastName,
+ const char* reason)
+{
+ PROTORECVEVENT pre = {0};
+
+ CCSDATA ccs = {0};
+ ccs.szProtoService = PSR_AUTH;
+ ccs.hContact = this->GetContactBySid(::mir_a2u(sid));
+ ccs.wParam = 0;
+ ccs.lParam = (LPARAM)⪯
+ pre.timestamp = timestamp;
+ pre.lParam = (DWORD)
+ (sizeof(DWORD) * 2) +
+ ::strlen(nick) +
+ ::strlen(firstName) +
+ ::strlen(lastName) +
+ ::strlen(sid) +
+ ::strlen(reason) +
+ 5;
+
+ /*blob is: 0(DWORD), hContact(DWORD), nick(ASCIIZ), firstName(ASCIIZ), lastName(ASCIIZ), sid(ASCIIZ), reason(ASCIIZ)*/
+ char *pCurBlob = pre.szMessage = (char*)::mir_alloc(pre.lParam);
+
+ *((PDWORD)pCurBlob) = 0; pCurBlob += sizeof(DWORD);
+ *((PDWORD)pCurBlob) = (DWORD)ccs.hContact; pCurBlob += sizeof(DWORD);
+ ::strcpy((char*)pCurBlob, nick); pCurBlob += ::strlen(nick) + 1;
+ ::strcpy((char*)pCurBlob, firstName); pCurBlob += ::strlen(sid) + 1;
+ ::strcpy((char*)pCurBlob, lastName); pCurBlob += ::strlen(sid) + 1;
+ ::strcpy((char*)pCurBlob, sid); pCurBlob += ::strlen(sid) + 1;
+ ::strcpy((char*)pCurBlob, reason);
+
+ ::CallService(MS_PROTO_CHAINRECV, 0, (LPARAM)&ccs);
+}
\ No newline at end of file diff --git a/protocols/Skype/src/skype_events.cpp b/protocols/Skype/src/skype_events.cpp index 1546ed6e85..ef97109d6f 100644 --- a/protocols/Skype/src/skype_events.cpp +++ b/protocols/Skype/src/skype_events.cpp @@ -13,3 +13,10 @@ int CSkypeProto::OnPreShutdown(WPARAM, LPARAM) return 0;
}
+
+int CSkypeProto::OnContactDeleted(WPARAM wParam, LPARAM)
+{
+ this->RemoveContact((HANDLE)wParam);
+
+ return 0;
+}
diff --git a/protocols/Skype/src/skype_proto.cpp b/protocols/Skype/src/skype_proto.cpp index e4c6170c76..75f2686eae 100644 --- a/protocols/Skype/src/skype_proto.cpp +++ b/protocols/Skype/src/skype_proto.cpp @@ -34,10 +34,10 @@ CSkypeProto::~CSkypeProto() HANDLE __cdecl CSkypeProto::AddToList(int flags, PROTOSEARCHRESULT* psr)
{
- if (psr->cbSize != sizeof(PROTOSEARCHRESULT))
+ //if (psr->cbSize != sizeof(PROTOSEARCHRESULT))
return 0;
- return this->AddContactBySkypeName(psr->id, psr->nick, flags);
+ //return this->AddContactBySkypeName(psr->id, psr->nick, flags);
}
HANDLE __cdecl CSkypeProto::AddToListByEvent(int flags, int iContact, HANDLE hDbEvent)
@@ -45,7 +45,7 @@ HANDLE __cdecl CSkypeProto::AddToListByEvent(int flags, int iContact, HANDLE hDb DBEVENTINFO dbei = {0};
dbei.cbSize = sizeof(dbei);
- if ((dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0)) != -1)
+ /*if ((dbei.cbBlob = CallService(MS_DB_EVENT_GETBLOBSIZE, (WPARAM)hDbEvent, 0)) != -1)
{
dbei.pBlob = (PBYTE)alloca(dbei.cbBlob);
if (CallService(MS_DB_EVENT_GET, (WPARAM)hDbEvent, (LPARAM)&dbei) == 0 &&
@@ -58,14 +58,85 @@ HANDLE __cdecl CSkypeProto::AddToListByEvent(int flags, int iContact, HANDLE hDb char *skypeName = lastName + strlen(lastName) + 1;
return AddContactBySkypeName(::mir_a2u(skypeName), ::mir_a2u(nick), 0);
}
+ }*/
+ return 0;
+}
+
+int __cdecl CSkypeProto::Authorize(HANDLE hDbEvent)
+{
+ if (this->IsOnline() && hDbEvent)
+ {
+ HANDLE hContact = this->GetContactFromAuthEvent(hDbEvent);
+ if (hContact == INVALID_HANDLE_VALUE)
+ return 1;
+
+ CContact::Ref contact;
+ SEString sid(::mir_u2a(this->GetSettingString(hContact, "sid")));
+ g_skype->GetContact(sid, contact);
+ contact->SetBuddyStatus(true/*Contact::AUTHORIZED_BY_ME*/);
+
+ return 0;
}
+
+ return 1;
+}
+
+int __cdecl CSkypeProto::AuthDeny(HANDLE hDbEvent, const TCHAR* szReason)
+{
+ if (this->IsOnline())
+ {
+ HANDLE hContact = this->GetContactFromAuthEvent(hDbEvent);
+ if (hContact == INVALID_HANDLE_VALUE)
+ return 1;
+
+ CContact::Ref contact;
+ SEString sid(::mir_u2a(this->GetSettingString(hContact, "SkypeName")));
+ g_skype->GetContact(sid, contact);
+ contact->SetBuddyStatus(false/*CContact::BLOCKED_BY_ME*/);
+
+ return 0;
+ }
+
+ return 1;
+}
+
+int __cdecl CSkypeProto::AuthRecv(HANDLE hContact, PROTORECVEVENT* pre)
+{
+ DWORD flags = 0;
+
+ if (pre->flags & PREF_CREATEREAD)
+ flags |= DBEF_READ;
+
+ if (pre->flags & PREF_UTF)
+ flags |= DBEF_UTF;
+
+ this->AddDataBaseEvent(
+ hContact,
+ EVENTTYPE_AUTHREQUEST,
+ pre->timestamp,
+ flags,
+ pre->lParam,
+ (PBYTE)pre->szMessage);
+
return 0;
}
-int __cdecl CSkypeProto::Authorize( HANDLE hDbEvent ) { return 0; }
-int __cdecl CSkypeProto::AuthDeny( HANDLE hDbEvent, const TCHAR* szReason ) { return 0; }
-int __cdecl CSkypeProto::AuthRecv( HANDLE hContact, PROTORECVEVENT* ) { return 0; }
-int __cdecl CSkypeProto::AuthRequest( HANDLE hContact, const TCHAR* szMessage ) { return 0; }
+int __cdecl CSkypeProto::AuthRequest(HANDLE hContact, const TCHAR* szMessage)
+{
+ if (this->IsOnline() && hContact)
+ {
+ CContact::Ref contact;
+ SEString sid(::mir_u2a(this->GetSettingString(hContact, "SkypeName")));
+ g_skype->GetContact(sid, contact);
+
+ contact->SendAuthRequest(::mir_u2a(szMessage));
+ this->DeleteSetting(hContact, "Grant");
+
+ return 0;
+ }
+
+ return 1;
+}
HANDLE __cdecl CSkypeProto::ChangeInfo( int iInfoType, void* pInfoData ) { return 0; }
@@ -153,8 +224,8 @@ int CSkypeProto::SetStatus(int new_status) this->m_iStatus = ID_STATUS_CONNECTING;
this->password = this->GetDecodeSettingString(SKYPE_SETTINGS_PASSWORD);
- this->ForkThread(&CSkypeProto::SignIn, this);
- //this->SignIn(this);
+ //this->ForkThread(&CSkypeProto::SignIn, this);
+ this->SignIn(this);
}
}
@@ -180,10 +251,13 @@ int __cdecl CSkypeProto::OnEvent(PROTOEVENTTYPE eventType, WPARAM wParam, LPA switch (eventType)
{
case EV_PROTO_ONLOAD:
- return this->OnModulesLoaded(0, 0);
+ return this->OnModulesLoaded(wParam, lParam);
case EV_PROTO_ONEXIT:
- return this->OnPreShutdown(0, 0);
+ return this->OnPreShutdown(wParam, lParam);
+
+ case EV_PROTO_ONCONTACTDELETED:
+ return this->OnContactDeleted(wParam, lParam);
}
return 1;
@@ -201,4 +275,9 @@ void __cdecl CSkypeProto::SignIn(void*) //this->LoadContactList(this);
ReleaseMutex(this->signin_lock);
+}
+
+bool CSkypeProto::IsOnline()
+{
+ return this->m_iStatus != ID_STATUS_OFFLINE;
}
\ No newline at end of file diff --git a/protocols/Skype/src/skype_proto.h b/protocols/Skype/src/skype_proto.h index 8ae37492c8..37d869d581 100644 --- a/protocols/Skype/src/skype_proto.h +++ b/protocols/Skype/src/skype_proto.h @@ -79,6 +79,7 @@ public: // events
int __cdecl OnModulesLoaded(WPARAM, LPARAM);
int __cdecl OnPreShutdown(WPARAM, LPARAM);
+ int __cdecl OnContactDeleted(WPARAM, LPARAM);
int __cdecl OnOptionsInit(WPARAM, LPARAM);
int __cdecl OnAccountManagerInit(WPARAM wParam, LPARAM lParam);
@@ -103,7 +104,7 @@ public: protected:
CAccount::Ref account;
- CContactGroup::Ref contactGroup;
+ CContactGroup::Ref contactList;
TCHAR* login;
TCHAR* password;
@@ -111,19 +112,42 @@ protected: HANDLE signin_lock;
void __cdecl SignIn(void*);
- void LoadContactInfo(HANDLE hContact, CContact::Ref contact);
- void __cdecl LoadContactList(void*);
+ bool IsOnline();
// contacts
- void OnContactChanged(CContact* contact, int prop);
+ void UpdateContactAboutText(HANDLE hContact, CContact::Ref contact);
+ void UpdateContactAuthState(HANDLE hContact, CContact::Ref contact);
+ void UpdateContactAvatar(HANDLE hContact, CContact::Ref contact);
+ void UpdateContactBirthday(HANDLE hContact, CContact::Ref contact);
+ void UpdateContactCity(HANDLE hContact, CContact::Ref contact);
+ void UpdateContactCountry(HANDLE hContact, CContact::Ref contact);
+ void UpdateContactEmails(HANDLE hContact, CContact::Ref contact);
+ void UpdateContactGender(HANDLE hContact, CContact::Ref contact);
+ void UpdateContactHomepage(HANDLE hContact, CContact::Ref contact);
+ void UpdateContactLanguages(HANDLE hContact, CContact::Ref contact);
+ void UpdateContactMobilePhone(HANDLE hContact, CContact::Ref contact);
+ void UpdateContactPhone(HANDLE hContact, CContact::Ref contact);
+ void UpdateContactOfficePhone(HANDLE hContact, CContact::Ref contact);
+ void UpdateContactState(HANDLE hContact, CContact::Ref contact);
+ void UpdateContactStatus(HANDLE hContact, CContact::Ref contact);
+ void UpdateContactStatusMessage(HANDLE hContact, CContact::Ref contact);
+ void UpdateContactTimezone(HANDLE hContact, CContact::Ref contact);
+ void UpdateContactProfile(HANDLE hContact, CContact::Ref contact);
+
+ void OnContactChanged(CContact::Ref contact, int prop);
+ void OnContactListChanged(const ContactRef& contact);
bool IsProtoContact(HANDLE hContact);
- HANDLE AddContactBySkypeName(wchar_t* skypeName, wchar_t* displayName, DWORD flags);
- HANDLE GetContactBySkypeName(wchar_t* skypeName);
+ HANDLE GetContactBySid(const wchar_t* sid);
+ HANDLE GetContactFromAuthEvent(HANDLE hEvent);
+ HANDLE AddContactBySid(const wchar_t* skypeName, const wchar_t* nick, DWORD flags = 0);
+ void RemoveContact(HANDLE hContact);
int SkypeToMirandaStatus(CContact::AVAILABILITY availability);
CContact::AVAILABILITY MirandaToSkypeStatus(int status);
void SetAllContactStatus(int status);
+ void __cdecl LoadContactList(void*);
+
// utils
static char* GetCountryNameById(int countryId);
static int GetCountryIdByName(const char* countryName);
@@ -163,6 +187,16 @@ protected: int OnPrebuildContactMenu(WPARAM wParam, LPARAM);
+ // database
+ HANDLE AddDataBaseEvent(HANDLE hContact, WORD type, DWORD time, DWORD flags, DWORD cbBlob, PBYTE pBlob);
+ void RaiseAuthRequestEvent(
+ DWORD timestamp,
+ const char* sid,
+ const char* nick,
+ const char* firstName = "",
+ const char* lastName = "",
+ const char* reason = "");
+
// database settings
BYTE GetSettingByte(const char *setting, BYTE errorValue = 0);
BYTE GetSettingByte(HANDLE hContact, const char *setting, BYTE errorValue = 0);
@@ -181,10 +215,10 @@ protected: bool SetSettingWord(HANDLE hContact, const char *setting, WORD value);
bool SetSettingDword(const char *setting, DWORD value);
bool SetSettingDword(HANDLE hContact, const char *setting, DWORD value);
- bool SetSettingString(const char *setting, wchar_t* value);
- bool SetSettingString(HANDLE hContact, const char *setting, wchar_t* value);
- bool SetDecodeSettingString(const char *setting, wchar_t* value);
- bool SetDecodeSettingString(HANDLE hContact, const char *setting, wchar_t* value);
+ bool SetSettingString(const char *setting, const wchar_t* value);
+ bool SetSettingString(HANDLE hContact, const char *setting, const wchar_t* value);
+ bool SetDecodeSettingString(const char *setting, const wchar_t* value);
+ bool SetDecodeSettingString(HANDLE hContact, const char *setting, const wchar_t* value);
//
void DeleteSetting(const char *setting);
void DeleteSetting(HANDLE hContact, const char *setting);
diff --git a/protocols/Skype/src/skype_settings.cpp b/protocols/Skype/src/skype_settings.cpp index 5cbe890268..88826fb613 100644 --- a/protocols/Skype/src/skype_settings.cpp +++ b/protocols/Skype/src/skype_settings.cpp @@ -33,7 +33,7 @@ DWORD CSkypeProto::GetSettingDword(const char *setting, DWORD errorValue) wchar_t* CSkypeProto::GetSettingString(HANDLE hContact, const char *setting, wchar_t* errorValue)
{
DBVARIANT dbv;
- TCHAR* result = NULL;
+ wchar_t* result = NULL;
if ( !::DBGetContactSettingWString(hContact, this->m_szModuleName, setting, &dbv))
{
@@ -98,17 +98,17 @@ bool CSkypeProto::SetSettingDword(const char *setting, DWORD value) return this->SetSettingDword(NULL, setting, value);
}
-bool CSkypeProto::SetSettingString(HANDLE hContact, const char *szSetting, wchar_t* value)
+bool CSkypeProto::SetSettingString(HANDLE hContact, const char *szSetting, const wchar_t* value)
{
return !::DBWriteContactSettingWString(hContact, this->m_szModuleName, szSetting, value);
}
-bool CSkypeProto::SetSettingString(const char *szSetting, wchar_t* value)
+bool CSkypeProto::SetSettingString(const char *szSetting, const wchar_t* value)
{
return this->SetSettingString(NULL, szSetting, value);
}
-bool CSkypeProto::SetDecodeSettingString(HANDLE hContact, const char *setting, wchar_t* value)
+bool CSkypeProto::SetDecodeSettingString(HANDLE hContact, const char *setting, const wchar_t* value)
{
TCHAR* result = mir_wstrdup(value);
CallService(MS_DB_CRYPT_ENCODESTRING, sizeof(result), reinterpret_cast<LPARAM>(result));
@@ -116,7 +116,7 @@ bool CSkypeProto::SetDecodeSettingString(HANDLE hContact, const char *setting, w return !this->SetSettingString(hContact, setting, result);
}
-bool CSkypeProto::SetDecodeSettingString(const char *setting, wchar_t* value)
+bool CSkypeProto::SetDecodeSettingString(const char *setting, const wchar_t* value)
{
return this->SetDecodeSettingString(NULL, setting, value);
}
diff --git a/protocols/Skype/src/skype_subclassing.cpp b/protocols/Skype/src/skype_subclassing.cpp index bb943a708e..c7752eeca9 100644 --- a/protocols/Skype/src/skype_subclassing.cpp +++ b/protocols/Skype/src/skype_subclassing.cpp @@ -1,5 +1,7 @@ #include "skype_subclassing.h" +// CSkype + CAccount* CSkype::newAccount(int oid) { return new CAccount(oid, this); @@ -15,6 +17,13 @@ CContact* CSkype::newContact(int oid) return new CContact(oid, this); } +CConversation* CSkype::newConversation(int oid) +{ + return new CConversation(oid, this); +} + +// CAccount + CAccount::CAccount(unsigned int oid, SERootObject* root) : Account(oid, root) { this->isLoggedOut = true; @@ -55,14 +64,32 @@ void CAccount::BlockWhileLoggingOut() Sleep(1); } +// CContactGroup + CContactGroup::CContactGroup(unsigned int oid, SERootObject* root) : ContactGroup(oid, root) { + this->proto = NULL; + this->callback == NULL; +} + +void CContactGroup::SetOnContactListChangedCallback(OnContactListChanged callback, CSkypeProto* proto) +{ + this->proto = proto; + this->callback = callback; +} + +bool CContactGroup::Contains(const ContactRef& contact) +{ + return this->ContactList.contains(contact); } void CContactGroup::OnChange(const ContactRef& contact) { + if (this->proto) + (proto->*callback)(contact); } +// CContact CContact::CContact(unsigned int oid, SERootObject* root) : Contact(oid, root) { @@ -70,7 +97,7 @@ CContact::CContact(unsigned int oid, SERootObject* root) : Contact(oid, root) this->callback == NULL; } -void CContact::SetOnContactChangeCallback(OnContactChangeFunc callback, CSkypeProto* proto) +void CContact::SetOnContactChangedCallback(OnContactChanged callback, CSkypeProto* proto) { this->proto = proto; this->callback = callback; @@ -78,6 +105,15 @@ void CContact::SetOnContactChangeCallback(OnContactChangeFunc callback, CSkypePr void CContact::OnChange(int prop) { - if (this->callback && this->proto) - (proto->*callback)(this, prop); + if (this->proto) + (proto->*callback)(this->ref(), prop); +} + +// Conversation + +CConversation::CConversation(unsigned int oid, SERootObject* root) : Conversation(oid, root) {} + +void CConversation::OnMessage(const MessageRef & message)
+{
+ // Message handling goes here
}
\ No newline at end of file diff --git a/protocols/Skype/src/skype_subclassing.h b/protocols/Skype/src/skype_subclassing.h index a4ea9a1264..bef67606a8 100644 --- a/protocols/Skype/src/skype_subclassing.h +++ b/protocols/Skype/src/skype_subclassing.h @@ -5,25 +5,35 @@ #include <skype-embedded_2.h>
-class CContact;
struct CSkypeProto;
-typedef void (CSkypeProto::* OnContactChangeFunc)(CContact* contact, int);
+class CConversation : public Conversation
+{
+public:
+ typedef DRef<CConversation, Conversation> Ref;
+ typedef DRefs<CConversation, Conversation> Refs;
+
+ CConversation(unsigned int oid, SERootObject* root);// : Conversation(oid, root) {};
+
+protected:
+ void OnMessage(const MessageRef & message);
+};
class CContact : public Contact {
public:
+ typedef void (CSkypeProto::* OnContactChanged)(CContact::Ref contact, int);
+
typedef DRef<CContact, Contact> Ref;
typedef DRefs<CContact, Contact> Refs;
CContact(unsigned int oid, SERootObject* root); - void SetOnContactChangeCallback(OnContactChangeFunc callback, CSkypeProto* proto); + void SetOnContactChangedCallback(OnContactChanged callback, CSkypeProto* proto); private: - CSkypeProto* proto;
-
- OnContactChangeFunc callback; + CSkypeProto* proto;
+ OnContactChanged callback; void OnChange(int prop); };
@@ -31,13 +41,21 @@ private: class CContactGroup : public ContactGroup
{
public:
+ typedef void (CSkypeProto::* OnContactListChanged)(const ContactRef& contact);
+
typedef DRef<CContactGroup, ContactGroup> Ref;
typedef DRefs<CContactGroup, ContactGroup> Refs;
CContactGroup(unsigned int oid, SERootObject* root);
CContact::Refs ContactList;
+ void SetOnContactListChangedCallback(OnContactListChanged callback, CSkypeProto* proto);
+
+ bool Contains(const ContactRef& contact);
private:
+ CSkypeProto* proto;
+ OnContactListChanged callback;
+
void OnChange(const ContactRef& contact);
}; @@ -63,5 +81,6 @@ class CSkype : public Skype public:
CAccount* newAccount(int oid);
CContactGroup* newContactGroup(int oid);
+ CConversation* newConversation(int oid);
CContact* newContact(int oid);
};
\ No newline at end of file |