From 5560fccb85a89bb668a79eed3d4cd0e668278331 Mon Sep 17 00:00:00 2001 From: Alexander Lantsev Date: Sat, 20 Apr 2013 10:14:05 +0000 Subject: - temporary commit. may contain non-working code git-svn-id: http://svn.miranda-ng.org/main/trunk@4480 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Skype/src/skype_account.cpp | 21 ++++ protocols/Skype/src/skype_contacts.cpp | 151 +++++++++++------------------ protocols/Skype/src/skype_database.cpp | 156 ++++++++++++++++++++---------- protocols/Skype/src/skype_dialogs.cpp | 2 +- protocols/Skype/src/skype_events.cpp | 120 +++++++++++++---------- protocols/Skype/src/skype_profile.cpp | 25 +++++ protocols/Skype/src/skype_proto.cpp | 29 +++--- protocols/Skype/src/skype_proto.h | 68 +++++-------- protocols/Skype/src/skype_services.cpp | 46 ++------- protocols/Skype/src/skype_subclassing.cpp | 27 ++++++ protocols/Skype/src/skype_subclassing.h | 4 + protocols/Skype/src/skype_utils.cpp | 28 +++++- 12 files changed, 381 insertions(+), 296 deletions(-) (limited to 'protocols/Skype/src') diff --git a/protocols/Skype/src/skype_account.cpp b/protocols/Skype/src/skype_account.cpp index 3bbf06bab3..6453e5e166 100644 --- a/protocols/Skype/src/skype_account.cpp +++ b/protocols/Skype/src/skype_account.cpp @@ -159,4 +159,25 @@ bool CSkypeProto::SignIn(int status) } return false; +} + +bool CSkypeProto::IsAvatarChanged(const SEBinary &avatar) +{ + bool result = false; + + ::mir_md5_byte_t digest[16]; + ::mir_md5_hash((PBYTE)avatar.data(), avatar.size(), digest); + + DBVARIANT dbv; + ::db_get(NULL, this->m_szModuleName, "AvatarHash", &dbv); + if (dbv.type == DBVT_BLOB && dbv.pbVal && dbv.cpbVal == 16) + { + if (::memcmp(digest, dbv.pbVal, 16) == 0) + { + result = true; + } + } + ::db_free(&dbv); + + return result; } \ No newline at end of file diff --git a/protocols/Skype/src/skype_contacts.cpp b/protocols/Skype/src/skype_contacts.cpp index 0ed653c7e6..e8d794fcb7 100644 --- a/protocols/Skype/src/skype_contacts.cpp +++ b/protocols/Skype/src/skype_contacts.cpp @@ -83,23 +83,7 @@ void CSkypeProto::OnContactChanged(CContact::Ref contact, int prop) DWORD oldTS = this->GetSettingDword(hContact, "AuthTS"); if (newTS > oldTS) { - contact->GetPropDisplayname(data); - char* nick = ::mir_utf8decodeA((const char*)data); - - contact->GetPropReceivedAuthrequest(data); - char* reason = ::mir_utf8decodeA((const char*)data); - - contact->GetPropFullname(data); - char* fullname = ::mir_utf8decodeA((const char*)data); - - char* first = strtok(fullname, " "); - char* last = strtok(NULL, " "); - if (last == NULL) - { - last = ""; - } - - this->RaiseAuthRequestEvent(newTS, sid, nick, first, last, reason); + this->RaiseAuthRequestEvent(newTS, contact); } } break; @@ -154,26 +138,7 @@ void CSkypeProto::OnContactListChanged(const ContactRef& contact) uint newTS = 0; contact->GetPropAuthreqTimestamp(newTS); - contact->GetPropSkypename(data); - 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); - - contact->GetPropFullname(data); - char* fullname = ::mir_utf8decodeA((const char*)data); - - char* first = strtok(fullname, " "); - char* last = strtok(NULL, " "); - if (last == NULL) - { - last = ""; - } - - this->RaiseAuthRequestEvent(newTS, sid, nick, first, last, reason); + this->RaiseAuthRequestEvent(newTS, contact); } } @@ -219,34 +184,60 @@ HANDLE CSkypeProto::GetContactFromAuthEvent(HANDLE hEvent) return ::DbGetAuthEventContact(&dbei); } -HANDLE CSkypeProto::AddContactBySid(const char* sid, const char* nick, DWORD flags) +HANDLE CSkypeProto::AddContact(CContact::Ref contact) { + SEString data; + + contact->GetPropSkypename(data); + char *sid = ::mir_strdup(data); + + CContact::AVAILABILITY availability; + contact->GetPropAvailability(availability); + + if (availability == CContact::SKYPEOUT) + { + //flags |= 256; + contact->GetPropPstnnumber(data); + ::mir_free(sid); + sid = ::mir_strdup((const char *)data); + } + 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); + char *nick; + if (availability == CContact::SKYPEOUT) + { + nick = ::mir_strdup(sid); + this->SetSettingByte(hContact, "IsSkypeOut", 1); + } + else + { + contact->GetPropDisplayname(data); + nick = ::mir_utf8decodeA(data); + } + ::db_set_s(hContact, this->m_szModuleName, "sid", sid); ::db_set_s(hContact, this->m_szModuleName, "Nick", nick); + + ::mir_free(nick); - CContact::Ref contact; - if (this->skype->GetContact(sid, contact)) + // why i do this? + /*bool result; + if (contact->IsMemberOfHardwiredGroup(CContactGroup::ALL_BUDDIES, result)) { - contact.fetch(); - bool result; - if (contact->IsMemberOfHardwiredGroup(CContactGroup::ALL_BUDDIES, result)) + CContactGroup::Ref group; + if (this->skype->GetHardwiredContactGroup(CContactGroup::ALL_BUDDIES, group)) { - CContactGroup::Ref group; - if (this->skype->GetHardwiredContactGroup(CContactGroup::ALL_BUDDIES, group)) - { - group.fetch(); - group->AddContact(contact); - } + group.fetch(); + group->AddContact(contact); } - } + }*/ - if (flags & 256) + /*if (flags & 256) { this->SetSettingByte(hContact, "IsSkypeOut", 1); } @@ -262,13 +253,15 @@ HANDLE CSkypeProto::AddContactBySid(const char* sid, const char* nick, DWORD fla ::db_set_b(hContact, "CList", "NotOnList", 1); ::db_set_b(hContact, "CList", "Hidden", 1); } - } + }*/ } - else + /*else { if ( !(flags & PALF_TEMPORARY)) ::db_unset(hContact, "CList", "NotOnList"); - } + }*/ + + ::mir_free(sid); return hContact; } @@ -290,32 +283,11 @@ void __cdecl CSkypeProto::LoadContactList(void*) (CContact::OnContactChanged)&CSkypeProto::OnContactChanged, this); - SEString data; - - contact->GetPropSkypename(data); - char *sid = ::mir_strdup(data); - - contact->GetPropDisplayname(data); - char *nick = ::mir_utf8decodeA(data); - - contact->GetPropFullname(data); - char *name = ::mir_utf8decodeA(data); - DWORD flags = 0; CContact::AVAILABILITY availability; contact->GetPropAvailability(availability); - if (availability == CContact::SKYPEOUT) - { - flags |= 256; - contact->GetPropPstnnumber(data); - ::mir_free(sid); - sid = ::mir_strdup((const char *)data); - } - else if (availability == CContact::PENDINGAUTH) - flags = PALF_TEMPORARY; - - HANDLE hContact = this->AddContactBySid(sid, nick, flags); + HANDLE hContact = this->AddContact(contact); SEObject *obj = contact.fetch(); this->UpdateContactAuthState(hContact, contact); @@ -325,7 +297,10 @@ void __cdecl CSkypeProto::LoadContactList(void*) this->UpdateProfileAvatar(obj, hContact); this->UpdateProfileStatusMessage(obj, hContact); } +} +void __cdecl CSkypeProto::LoadChatList(void*) +{ //CConversation::Refs conversations; //this->skype->GetConversationList(conversations); //for (uint i = 0; i < conversations.size(); i++) @@ -364,7 +339,10 @@ void __cdecl CSkypeProto::LoadContactList(void*) { conversations[i]->Delete(); }*/ +} +void __cdecl CSkypeProto::LoadAuthWaitList(void*) +{ // raise auth event for all non auth contacts CContact::Refs authContacts; this->skype->GetHardwiredContactGroup(CContactGroup::CONTACTS_WAITING_MY_AUTHORIZATION, this->authWaitList); @@ -399,35 +377,22 @@ void __cdecl CSkypeProto::LoadContactList(void*) sid = (const char*)data; } - contact->GetPropDisplayname(data); - char* nick = ::mir_utf8decodeA((const char *)data); - - contact->GetPropReceivedAuthrequest(data); - char* reason = ::mir_utf8decodeA((const char *)data); - - contact->GetPropFullname(data); - char* fullname = ::mir_utf8decodeA((const char *)data); - - char* first = strtok(fullname, " "); - char* last = strtok(NULL, " "); - if (last == NULL) last = ""; - - this->RaiseAuthRequestEvent(newTS, sid, nick, first, last, reason); + this->RaiseAuthRequestEvent(newTS, contact); } } void CSkypeProto::SetAllContactStatus(int status) { - HANDLE hContact = db_find_first(); + HANDLE hContact = ::db_find_first(); while (hContact) { if (this->IsProtoContact(hContact)) { //if ( !this->GetSettingWord(hContact, SKYPE_SETTINGS_STATUS, ID_STATUS_OFFLINE) == status) - if( this->GetSettingByte(hContact, "IsSkypeOut", 0) == 0) + if ( this->GetSettingByte(hContact, "IsSkypeOut", 0) == 0) this->SetSettingWord(hContact, SKYPE_SETTINGS_STATUS, status); } - hContact = db_find_next(hContact); + hContact = ::db_find_next(hContact); } } diff --git a/protocols/Skype/src/skype_database.cpp b/protocols/Skype/src/skype_database.cpp index 50fac3651f..8623d08a7b 100644 --- a/protocols/Skype/src/skype_database.cpp +++ b/protocols/Skype/src/skype_database.cpp @@ -17,17 +17,34 @@ HANDLE CSkypeProto::AddDataBaseEvent(HANDLE hContact, WORD type, DWORD time, DWO void CSkypeProto::RaiseAuthRequestEvent( DWORD timestamp, - const char* sid, - const char* nick, - const char* firstName, - const char* lastName, - const char* reason) + CContact::Ref contact) { + SEString data; + + contact->GetPropSkypename(data); + char *sid = ::mir_strdup(data); + + contact->GetPropDisplayname(data); + char *nick = ::mir_utf8decodeA(data); + + contact->GetPropReceivedAuthrequest(data); + char* reason = ::mir_utf8decodeA((const char*)data); + + contact->GetPropFullname(data); + char* fullname = ::mir_utf8decodeA((const char*)data); + + char* firstName = strtok(fullname, " "); + char* lastName = strtok(NULL, " "); + if (lastName == NULL) + { + lastName = ""; + } + PROTORECVEVENT pre = {0}; CCSDATA ccs = {0}; ccs.szProtoService = PSR_AUTH; - ccs.hContact = this->AddContactBySid(sid, nick); + ccs.hContact = this->AddContact(contact); ccs.wParam = 0; ccs.lParam = (LPARAM)⪯ pre.timestamp = timestamp; @@ -54,62 +71,99 @@ void CSkypeProto::RaiseAuthRequestEvent( ::CallService(MS_PROTO_CHAINRECV, 0, (LPARAM)&ccs); } +bool CSkypeProto::IsMessageInDB(HANDLE hContact, DWORD timestamp, const char* message, int flag) +{ + bool result = false; + + int length = ::strlen(message); + + HANDLE hDbEvent = ::db_event_last(hContact); + while (hDbEvent) + { + DBEVENTINFO dbei = { sizeof(dbei) }; + dbei.cbBlob = ::db_event_getBlobSize(hDbEvent); + dbei.pBlob = (PBYTE)::mir_alloc(dbei.cbBlob); + ::db_event_get(hDbEvent, &dbei); + + if (dbei.timestamp < timestamp) + { + ::mir_free(dbei.pBlob); + break; + } + + int sendFlag = dbei.flags & DBEF_SENT; + if (dbei.eventType == EVENTTYPE_MESSAGE && sendFlag == flag) + { + char *dbMessage = (char *)dbei.pBlob; + if (::strncmp(dbMessage, message, length) == 0 && dbei.timestamp == timestamp) + { + ::mir_free(dbei.pBlob); + result = true; + break; + } + } + + ::mir_free(dbei.pBlob); + hDbEvent = ::db_event_prev(hDbEvent); + } + + return result; +} + void CSkypeProto::RaiseMessageReceivedEvent( + HANDLE hContact, DWORD timestamp, - const char* sid, - const char* nick, - const char* message) + const char* message, + bool isNeedCheck) { - PROTORECVEVENT pre = {0}; + if (isNeedCheck) + if (this->IsMessageInDB(hContact, timestamp, message)) + return; - CCSDATA ccs = {0}; - ccs.szProtoService = PSR_MESSAGE; - ccs.hContact = this->AddContactBySid(sid, nick); - ccs.wParam = 0; - ccs.lParam = (LPARAM)⪯ - pre.flags = PREF_UTF; - pre.timestamp = timestamp; - pre.szMessage = (char *)message; + PROTORECVEVENT recv; + recv.flags = PREF_UTF; + recv.timestamp = timestamp; + recv.szMessage = ::mir_strdup(message); - ::CallService(MS_PROTO_CHAINRECV, 0, (LPARAM)&ccs); + ::ProtoChainRecvMsg(hContact, &recv); } void CSkypeProto::RaiseMessageSendedEvent( + HANDLE hContact, DWORD timestamp, - const char* sid, - const char* nick, const char* message) { - PROTORECVEVENT pre = {0}; + if (this->IsMessageInDB(hContact, timestamp, message, DBEF_SENT)) + return; - CCSDATA ccs = {0}; - ccs.szProtoService = PSR_MESSAGE; - ccs.hContact = this->AddContactBySid(sid, nick); - ccs.wParam = 0; - ccs.lParam = (LPARAM)⪯ - pre.flags = PREF_UTF; - pre.timestamp = timestamp; - pre.szMessage = (char *)message; - - ::CallService(MS_PROTO_CHAINSEND, 0, (LPARAM)&ccs); -} + DBEVENTINFO dbei = { 0 }; + dbei.cbSize = sizeof(dbei); + dbei.szModule = this->m_szModuleName; + dbei.timestamp = timestamp; + dbei.eventType = EVENTTYPE_MESSAGE; + dbei.cbBlob = (DWORD)::strlen(message) + 1; + dbei.pBlob = (PBYTE)::mir_strdup(message); + dbei.flags = DBEF_UTF | DBEF_SENT; -void CSkypeProto::RaiseFileReceivedEvent( - DWORD timestamp, - const char* sid, - const char* nick, - const char* message) -{ - PROTORECVFILET pre = {0}; + ::db_event_add(hContact, &dbei); +} - CCSDATA ccs = {0}; - ccs.szProtoService = PSR_FILE; - ccs.hContact = this->AddContactBySid(sid, nick); - ccs.wParam = 0; - ccs.lParam = (LPARAM)⪯ - pre.flags = PREF_UTF; - pre.timestamp = timestamp; - //pre.szMessage = (char *)message; - - ::CallService(MS_PROTO_CHAINRECV, 0, (LPARAM)&ccs); -} \ No newline at end of file +//void CSkypeProto::RaiseFileReceivedEvent( +// DWORD timestamp, +// const char* sid, +// const char* nick, +// const char* message) +//{ +// PROTORECVFILET pre = {0}; +// +// CCSDATA ccs = {0}; +// ccs.szProtoService = PSR_FILE; +// ccs.hContact = this->AddContactBySid(sid, nick); +// ccs.wParam = 0; +// ccs.lParam = (LPARAM)⪯ +// pre.flags = PREF_UTF; +// pre.timestamp = timestamp; +// //pre.szMessage = (char *)message; +// +// ::CallService(MS_PROTO_CHAINRECV, 0, (LPARAM)&ccs); +//} \ No newline at end of file diff --git a/protocols/Skype/src/skype_dialogs.cpp b/protocols/Skype/src/skype_dialogs.cpp index 2327d2e4ce..c6ee03362d 100644 --- a/protocols/Skype/src/skype_dialogs.cpp +++ b/protocols/Skype/src/skype_dialogs.cpp @@ -450,7 +450,7 @@ INT_PTR CALLBACK CSkypeProto::OwnSkypeDlgProc(HWND hwndDlg, UINT msg, WPARAM wPa LV_ITEM lvi = {0}; lvi.mask = LVIF_PARAM | LVIF_TEXT; - for (lvi.iItem = 0; lvi.iItem < SIZEOF(setting); lvi.iItem++) + for (lvi.iItem = 0; lvi.iItem < SIZEOF(CSkypeProto::setting); lvi.iItem++) { lvi.lParam = lvi.iItem; lvi.pszText = (LPTSTR)setting[lvi.iItem].szDescription; diff --git a/protocols/Skype/src/skype_events.cpp b/protocols/Skype/src/skype_events.cpp index 82b24a16ba..07fe293e0b 100644 --- a/protocols/Skype/src/skype_events.cpp +++ b/protocols/Skype/src/skype_events.cpp @@ -50,40 +50,47 @@ int CSkypeProto::OnContactDeleted(WPARAM wParam, LPARAM lParam) return 0; } -void CSkypeProto::OnMessageSended(CConversation::Ref conversation, CMessage::Ref message) +void CSkypeProto::OnMessageSended(CConversation::Ref conversation, CMessage::Ref message, CContact::Ref receiver) { SEString data; uint timestamp; message->GetPropTimestamp(timestamp); - message->GetPropAuthor(data); - char *sid = ::mir_strdup(data); + CMessage::SENDING_STATUS sstatus; + message->GetPropSendingStatus(sstatus); + + CMessage::CONSUMPTION_STATUS status; + message->GetPropConsumptionStatus(status); message->GetPropBodyXml(data); - char *text = ::mir_strdup(data); + char *text = CSkypeProto::RemoveHtml(data); CConversation::TYPE type; conversation->GetPropType(type); if (type == CConversation::DIALOG) { - CParticipant::Refs participants; - conversation->GetParticipants(participants, CConversation::OTHER_CONSUMERS); - - //for (uint i = 0; i < participants.size(); i ++) + HANDLE hContact = this->AddContact(receiver); + + if (sstatus != CMessage::SENDING) { - participants[0]->GetPropIdentity(data); - char *contactSid = ::mir_strdup(data); - //todo: get nickname + this->SendBroadcast( + hContact, + ACKTYPE_MESSAGE, + sstatus == CMessage::FAILED_TO_SEND ? ACKRESULT_FAILED : ACKRESULT_SUCCESS, + (HANDLE)message->getOID(), 0); + this->RaiseMessageSendedEvent( + hContact, timestamp, - contactSid, - contactSid, - CSkypeProto::RemoveHtml(text)); + text); } } else { + receiver->GetIdentity(data); + char *sid = ::mir_strdup(data); + conversation->GetPropIdentity(data); char *cid = ::mir_strdup(data); @@ -98,54 +105,56 @@ void CSkypeProto::OnMessageSended(CConversation::Ref conversation, CMessage::Ref this->SendChatMessage( cid, nick, - CSkypeProto::RemoveHtml(::mir_utf8decodeA(text))); + text); + ::mir_free(sid); ::mir_free(cid); } + + ::mir_free(text); } -void CSkypeProto::OnMessageReceived(CConversation::Ref conversation, CMessage::Ref message) +void CSkypeProto::OnMessageReceived(CConversation::Ref conversation, CMessage::Ref message, CContact::Ref author) { SEString data; uint timestamp; message->GetPropTimestamp(timestamp); - message->GetPropAuthor(data); - char *sid = ::mir_strdup(data); + CMessage::CONSUMPTION_STATUS status; + message->GetPropConsumptionStatus(status); message->GetPropBodyXml(data); - char *text = ::mir_strdup(data); + char *text = CSkypeProto::RemoveHtml(data); CConversation::TYPE type; conversation->GetPropType(type); if (type == CConversation::DIALOG) { - message->GetPropAuthorDisplayname(data); - char *nick = ::mir_utf8decodeA(data); + HANDLE hContact = this->AddContact(author); + // fixme this->RaiseMessageReceivedEvent( - (DWORD)timestamp, - sid, - nick, - CSkypeProto::RemoveHtml(text)); + hContact, + timestamp, + text, + status != CMessage::UNCONSUMED_NORMAL); } else { + message->GetPropAuthor(data); + char *sid = ::mir_strdup(data); + conversation->GetPropIdentity(data); char *cid = ::mir_strdup(data); - this->SendChatMessage(cid, sid, CSkypeProto::RemoveHtml(::mir_utf8decodeA(text))); + this->SendChatMessage(cid, sid, text); + ::mir_free(sid); ::mir_free(cid); } - - /*int len = ::strlen(text) + 8; - wchar_t *xml = new wchar_t[len]; - ::mir_sntprintf(xml, len, L"%s", ::mir_utf8decodeW(text)); - - int bytesProcessed = 0; - HXML hXml = xi.parseString(xml, &bytesProcessed, NULL);*/ + + ::mir_free(text); } void CSkypeProto::OnTransferChanged(int prop, CTransfer::Ref transfer) @@ -293,39 +302,44 @@ void CSkypeProto::OnMessage(CConversation::Ref conversation, CMessage::Ref messa CMessage::TYPE messageType; message->GetPropType(messageType); - CMessage::SENDING_STATUS sendingStatus; - message->GetPropSendingStatus(sendingStatus); - - if (messageType == CMessage::POSTED_FILES) - { - this->OnFileReceived(conversation, message); - return; - } - - CMessage::CONSUMPTION_STATUS status; - message->GetPropConsumptionStatus(status); + //CMessage::SENDING_STATUS sendingStatus; + //message->GetPropSendingStatus(sendingStatus); - // it's old message (hystory sync) - if (status == CMessage::CONSUMED && sendingStatus != CMessage::SENT) return; + //CMessage::CONSUMPTION_STATUS status; + //message->GetPropConsumptionStatus(status); switch (messageType) { case CMessage::POSTED_EMOTE: + //int i = 0; + break; + case CMessage::POSTED_TEXT: { - SEString data; - - message->GetPropAuthor(data); - char *sid = ::mir_strdup(data); - + SEString identity; + message->GetPropAuthor(identity); + char *sid = ::mir_strdup(identity); if (::stricmp(sid, this->login) == 0) - this->OnMessageSended(conversation, message); + { + CParticipant::Refs participants; + conversation->GetParticipants(participants, CConversation::OTHER_CONSUMERS); + participants[0]->GetPropIdentity(identity); + CContact::Ref receiver; + this->skype->GetContact(identity, receiver); + this->OnMessageSended(conversation, message, receiver); + } else - this->OnMessageReceived(conversation, message); + { + CContact::Ref author; + this->skype->GetContact(identity, author); + this->OnMessageReceived(conversation, message, author); + } + ::mir_free(sid); } break; case CMessage::POSTED_FILES: + this->OnFileReceived(conversation, message); break; case CMessage::ADDED_CONSUMERS: diff --git a/protocols/Skype/src/skype_profile.cpp b/protocols/Skype/src/skype_profile.cpp index ea35f7e482..81ef6fc48c 100644 --- a/protocols/Skype/src/skype_profile.cpp +++ b/protocols/Skype/src/skype_profile.cpp @@ -1,5 +1,30 @@ #include "skype_proto.h" +SettingItem CSkypeProto::setting[] = { + {LPGENT("Full name"), "Nick", DBVT_WCHAR, LI_STRING}, + {LPGENT("Mood"), "XStatusMsg", DBVT_WCHAR, LI_STRING}, + + {LPGENT("Mobile phone"), "Cellular", DBVT_WCHAR, LI_NUMBER}, + {LPGENT("Home phone"), "Phone", DBVT_WCHAR, LI_NUMBER}, + {LPGENT("Office phone"), "CompanyPhone", DBVT_WCHAR, LI_NUMBER}, + {LPGENT("E-mail 1"), "e-mail0", DBVT_WCHAR, LI_STRING}, + {LPGENT("E-mail 2"), "e-mail1", DBVT_WCHAR, LI_STRING}, + {LPGENT("E-mail 3"), "e-mail2", DBVT_WCHAR, LI_STRING}, + + {LPGENT("Country"), "Country", DBVT_WCHAR, LI_LIST}, + {LPGENT("State"), "State", DBVT_WCHAR, LI_STRING}, + {LPGENT("City"), "City", DBVT_WCHAR, LI_STRING}, + {LPGENT("Time zone"), "Timezone", DBVT_BYTE, LI_LIST}, + {LPGENT("Homepage"), "Homepage", DBVT_WCHAR, LI_STRING}, + {LPGENT("Gender"), "Gender", DBVT_BYTE, LI_LIST}, + {LPGENT("Birth day"), "BirthDay", DBVT_BYTE, LI_NUMBER}, + {LPGENT("Birth month"), "BirthMonth", DBVT_BYTE, LI_NUMBER}, + {LPGENT("Birth year"), "BirthYear", DBVT_WORD, LI_NUMBER}, + {LPGENT("Language"), "Language1", DBVT_WCHAR, LI_LIST}, + + {LPGENT("About"), "About", DBVT_WCHAR, LI_STRING} +}; + void CSkypeProto::UpdateProfileAvatar(SEObject *obj, HANDLE hContact) { uint newTS = obj->GetUintProp(/* *::P_AVATAR_TIMESTAMP */ 182); diff --git a/protocols/Skype/src/skype_proto.cpp b/protocols/Skype/src/skype_proto.cpp index c418556ef4..1571db1c0f 100644 --- a/protocols/Skype/src/skype_proto.cpp +++ b/protocols/Skype/src/skype_proto.cpp @@ -35,13 +35,16 @@ CSkypeProto::~CSkypeProto() this->password = NULL; } - ProtoDestructor(this); + ::ProtoDestructor(this); } HANDLE __cdecl CSkypeProto::AddToList(int flags, PROTOSEARCHRESULT* psr) { - //todo:ref - return this->AddContactBySid(::mir_u2a(psr->id), ::mir_u2a(psr->nick), 0); + //fixme + CContact::Ref contact; + this->skype->GetContact(::mir_u2a(psr->id), contact); + return this->AddContact(contact); + return 0; } HANDLE __cdecl CSkypeProto::AddToListByEvent(int flags, int iContact, HANDLE hDbEvent) @@ -325,24 +328,20 @@ HANDLE __cdecl CSkypeProto::SendFile( HANDLE hContact, const TCHAR* szDescriptio int __cdecl CSkypeProto::SendMsg(HANDLE hContact, int flags, const char* msg) { - int result = ::InterlockedIncrement((LONG volatile*)&dwCMDNum); - CConversation::Ref conversation = CConversation::FindBySid( this->skype, - ::db_get_sa(hContact, this->m_szModuleName, "sid")); + (char*)::mir_ptr(::db_get_sa(hContact, this->m_szModuleName, "sid"))); + if (conversation) { - Message::Ref message; - conversation->PostText(msg, message); - } + CMessage::Ref message; + if (!conversation->PostText(msg, message)) + return 0; - this->SendBroadcastAsync( - hContact, - ACKTYPE_MESSAGE, - ACKRESULT_SUCCESS, - (HANDLE)result, 0); + return message->getOID(); + } - return result; + return 0; } int __cdecl CSkypeProto::SendUrl( HANDLE hContact, int flags, const char* url ) { return 0; } diff --git a/protocols/Skype/src/skype_proto.h b/protocols/Skype/src/skype_proto.h index b1f37b3147..74acb0f38f 100644 --- a/protocols/Skype/src/skype_proto.h +++ b/protocols/Skype/src/skype_proto.h @@ -3,7 +3,6 @@ #include "skype.h" #include - struct CSkypeProto; typedef void (__cdecl CSkypeProto::* SkypeThreadFunc) (void*); @@ -90,32 +89,6 @@ struct SettingItem unsigned displayType; //LI_ constant }; -const SettingItem setting[]={ - {LPGENT("Full name"), "Nick", DBVT_WCHAR, LI_STRING}, - {LPGENT("Mood"), "XStatusMsg", DBVT_WCHAR, LI_STRING}, - - {LPGENT("Mobile phone"), "Cellular", DBVT_WCHAR, LI_NUMBER}, - {LPGENT("Home phone"), "Phone", DBVT_WCHAR, LI_NUMBER}, - {LPGENT("Office phone"), "CompanyPhone", DBVT_WCHAR, LI_NUMBER}, - {LPGENT("E-mail 1"), "e-mail0", DBVT_WCHAR, LI_STRING}, - {LPGENT("E-mail 2"), "e-mail1", DBVT_WCHAR, LI_STRING}, - {LPGENT("E-mail 3"), "e-mail2", DBVT_WCHAR, LI_STRING}, - - {LPGENT("Country"), "Country", DBVT_WCHAR, LI_LIST}, - {LPGENT("State"), "State", DBVT_WCHAR, LI_STRING}, - {LPGENT("City"), "City", DBVT_WCHAR, LI_STRING}, - {LPGENT("Time zone"), "Timezone", DBVT_BYTE, LI_LIST}, - {LPGENT("Homepage"), "Homepage", DBVT_WCHAR, LI_STRING}, - {LPGENT("Gender"), "Gender", DBVT_BYTE, LI_LIST}, - {LPGENT("Birth day"), "BirthDay", DBVT_BYTE, LI_NUMBER}, - {LPGENT("Birth month"), "BirthMonth", DBVT_BYTE, LI_NUMBER}, - {LPGENT("Birth year"), "BirthYear", DBVT_WORD, LI_NUMBER}, - {LPGENT("Language"), "Language1", DBVT_WCHAR, LI_LIST}, - - {LPGENT("About"), "About", DBVT_WCHAR, LI_STRING} -}; - - struct HtmlEntity { const char *entity; @@ -291,7 +264,6 @@ public: bool IsOnline(); protected: - DWORD dwCMDNum; CSkype *skype; CAccount::Ref account; CContact::Refs contactList; @@ -312,6 +284,10 @@ protected: bool SignIn(int status); void __cdecl SignInAsync(void*); + bool IsAvatarChanged(const SEBinary &avatar); + + static SettingItem setting[19]; + static wchar_t* LogoutReasons[]; static wchar_t* ValidationReasons[]; static wchar_t* PasswordChangeReasons[]; @@ -319,8 +295,8 @@ protected: // messages void OnMessage(CConversation::Ref conversation, CMessage::Ref message); - void OnMessageSended(CConversation::Ref conversation, CMessage::Ref message); - void OnMessageReceived(CConversation::Ref conversation, CMessage::Ref message); + void OnMessageSended(CConversation::Ref conversation, CMessage::Ref message, CContact::Ref receiver); + void OnMessageReceived(CConversation::Ref conversation, CMessage::Ref message, CContact::Ref author); // file transfer LIST fileTransferList; @@ -377,11 +353,14 @@ protected: bool IsProtoContact(HANDLE hContact); HANDLE GetContactBySid(const char* sid); HANDLE GetContactFromAuthEvent(HANDLE hEvent); - HANDLE AddContactBySid(const char* sid, const char* nick, DWORD flags = 0); + HANDLE AddContact(CContact::Ref contact); void SetAllContactStatus(int status); void __cdecl LoadContactList(void*); + void __cdecl LoadChatList(void*); + void __cdecl LoadAuthWaitList(void*); + void __cdecl SearchBySidAsync(void*); void __cdecl SearchByNamesAsync(void*); void __cdecl SearchByEmailAsync(void*); @@ -425,11 +404,13 @@ protected: static void ShowNotification(const wchar_t *message, int flags = 0, HANDLE hContact = NULL); static void ShowNotification(const wchar_t *caption, const wchar_t *message, int flags = 0, HANDLE hContact = NULL); - static char *RemoveHtml(char *data); + static char *RemoveHtml(const char *data); int SkypeToMirandaStatus(CContact::AVAILABILITY availability); CContact::AVAILABILITY MirandaToSkypeStatus(int status); + SEBinary GetAvatarBinary(wchar_t *path); + // runtime void InitSkype(); void UninitSkype(); @@ -480,29 +461,26 @@ protected: // database + bool IsMessageInDB(HANDLE hContact, DWORD timestamp, const char* guid, int flag = 0); + HANDLE AddDataBaseEvent(HANDLE hContact, WORD type, DWORD time, DWORD flags, DWORD cbBlob, PBYTE pBlob); void RaiseMessageReceivedEvent( + HANDLE hContact, DWORD timestamp, - const char* sid, - const char* nick, - const char* message = ""); + const char* message, + bool isNeedCheck = true); void RaiseMessageSendedEvent( + HANDLE hContact, DWORD timestamp, - const char* sid, - const char* nick, - const char* message = ""); - void RaiseFileReceivedEvent( + const char* message); + /*void RaiseFileReceivedEvent( DWORD timestamp, const char* sid, const char* nick, - const char* message = ""); + const char* message);*/ void RaiseAuthRequestEvent( DWORD timestamp, - const char* sid, - const char* nick, - const char* firstName = "", - const char* lastName = "", - const char* reason = ""); + CContact::Ref contact); // database settings BYTE GetSettingByte(const char *setting, BYTE errorValue = 0); diff --git a/protocols/Skype/src/skype_services.cpp b/protocols/Skype/src/skype_services.cpp index 509b3e422e..9b97771d6d 100644 --- a/protocols/Skype/src/skype_services.cpp +++ b/protocols/Skype/src/skype_services.cpp @@ -104,54 +104,28 @@ INT_PTR __cdecl CSkypeProto::SetMyAvatar(WPARAM, LPARAM lParam) return iRet; } - int len; - char *buffer; - FILE* fp = ::_wfopen(avatarPath, L"rb"); - if (!fp) + SEBinary avatar = this->GetAvatarBinary(avatarPath); + if (avatar.size() == 0) { - this->Log(L"Failed to read avatar in local storage."); + this->Log(L"Failed to read avatar file."); return iRet; } - ::fseek(fp, 0, SEEK_END); - len = ::ftell(fp); - ::fseek(fp, 0, SEEK_SET); - buffer = new char[len + 1]; - ::fread(buffer, len, 1, fp); - ::fclose(fp); - - ::mir_md5_byte_t digest[16]; - ::mir_md5_hash((BYTE*)buffer, len, digest); - - DBVARIANT dbv; - ::db_get(NULL, this->m_szModuleName, "AvatarHash", &dbv); - if (dbv.type == DBVT_BLOB && dbv.pbVal && dbv.cpbVal == 16) + + if (!this->IsAvatarChanged(avatar)) { - if (::memcmp(digest, dbv.pbVal, 16) == 0) - { - ::db_free(&dbv); - delete [] buffer; - return 0; - } + this->Log(L"New avatar are same with old."); + return iRet; } - ::db_free(&dbv); - int fbl; - SEBinary avatar(buffer, len); Skype::VALIDATERESULT result = Skype::NOT_VALIDATED; - if (!this->skype->ValidateAvatar(avatar, result, fbl) || result != Skype::VALIDATED_OK) + if (!this->account->SetAvatar(avatar, result)) { this->Log(CSkypeProto::ValidationReasons[result]); return iRet; } - if (!this->account->SetBinProperty(Account::P_AVATAR_IMAGE, avatar)) - { - this->Log(L"Failed to send avatar on server."); - return iRet; - } - - delete [] buffer; - this->SetSettingDword("AvatarTS", time(NULL)); + uint newTS = this->account->GetUintProp(/* *::P_AVATAR_TIMESTAMP */ 182); + this->SetSettingDword("AvatarTS", newTS); iRet = 0; } else diff --git a/protocols/Skype/src/skype_subclassing.cpp b/protocols/Skype/src/skype_subclassing.cpp index 5fbf7819d8..4d10e982c9 100644 --- a/protocols/Skype/src/skype_subclassing.cpp +++ b/protocols/Skype/src/skype_subclassing.cpp @@ -306,10 +306,24 @@ CAccount::CAccount(unsigned int oid, SERootObject* root) : Account(oid, root) void CAccount::SetOnAccountChangedCallback(OnAccountChanged callback, CSkypeProto* proto) { + this->skype = (CSkype *)root; + this->proto = proto; this->callback = callback; } +bool CAccount::SetAvatar(SEBinary avatar, Skype::VALIDATERESULT &result) +{ + int fbl; + if (!this->skype->ValidateAvatar(avatar, result, fbl) || result != Skype::VALIDATED_OK) + return false; + + if (!this->SetBinProperty(Account::P_AVATAR_IMAGE, avatar)) + return false; + + return true; +} + void CAccount::OnChange(int prop) { if (this->proto) @@ -464,6 +478,19 @@ void CConversation::OnMessage(const MessageRef & message) (proto->*messageReceivedCallback)(message->ref()); } +void CConversation::OnChange(int prop) +{ + if (prop == Conversation::P_LOCAL_LIVESTATUS) + { + Conversation::LOCAL_LIVESTATUS liveStatus; + this->GetPropLocalLivestatus(liveStatus); + if (liveStatus == Conversation::RINGING_FOR_ME) + { + + } + } +} + CConversation::Ref CConversation::FindBySid(CSkype *skype, SEString sid) { SEStringList participants; diff --git a/protocols/Skype/src/skype_subclassing.h b/protocols/Skype/src/skype_subclassing.h index b16f7d7e66..c6c65f3c74 100644 --- a/protocols/Skype/src/skype_subclassing.h +++ b/protocols/Skype/src/skype_subclassing.h @@ -67,6 +67,7 @@ private: OnMessageReceived messageReceivedCallback; void OnMessage(const MessageRef & message); + void OnChange(int prop); }; class CContact : public Contact @@ -146,10 +147,13 @@ public: typedef DRefs Refs; CAccount(unsigned int oid, SERootObject* root); + + bool SetAvatar(SEBinary avatar, Skype::VALIDATERESULT &result); void SetOnAccountChangedCallback(OnAccountChanged callback, CSkypeProto* proto); private: + CSkype *skype; CSkypeProto* proto; OnAccountChanged callback; void OnChange(int prop); diff --git a/protocols/Skype/src/skype_utils.cpp b/protocols/Skype/src/skype_utils.cpp index acc1ef33c5..4cb81a5c50 100644 --- a/protocols/Skype/src/skype_utils.cpp +++ b/protocols/Skype/src/skype_utils.cpp @@ -507,7 +507,7 @@ void CSkypeProto::ShowNotification(const wchar_t *message, int flags, HANDLE hCo CSkypeProto::ShowNotification(TranslateT("Skype Protocol"), message, flags, hContact); } -char *CSkypeProto::RemoveHtml(char *text) +char *CSkypeProto::RemoveHtml(const char *text) { std::string new_string = ""; std::string data = text; @@ -551,7 +551,6 @@ char *CSkypeProto::RemoveHtml(char *text) new_string += data.at(i); } - ::mir_free(text); return ::mir_strdup(new_string.c_str()); } @@ -617,4 +616,29 @@ CContact::AVAILABILITY CSkypeProto::MirandaToSkypeStatus(int status) } return availability; +} + +SEBinary CSkypeProto::GetAvatarBinary(wchar_t *path) +{ + SEBinary avatar; + + if (::PathFileExists(path)) + { + int len; + char *buffer; + FILE* fp = ::_wfopen(path, L"rb"); + if (fp) + { + ::fseek(fp, 0, SEEK_END); + len = ::ftell(fp); + ::fseek(fp, 0, SEEK_SET); + buffer = new char[len + 1]; + ::fread(buffer, len, 1, fp); + ::fclose(fp); + + avatar.set(buffer, len); + } + } + + return avatar; } \ No newline at end of file -- cgit v1.2.3