summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--protocols/Skype/Skype_10.vcxproj.filters16
-rw-r--r--protocols/Skype/src/skype_account.cpp21
-rw-r--r--protocols/Skype/src/skype_contacts.cpp151
-rw-r--r--protocols/Skype/src/skype_database.cpp156
-rw-r--r--protocols/Skype/src/skype_dialogs.cpp2
-rw-r--r--protocols/Skype/src/skype_events.cpp120
-rw-r--r--protocols/Skype/src/skype_profile.cpp25
-rw-r--r--protocols/Skype/src/skype_proto.cpp29
-rw-r--r--protocols/Skype/src/skype_proto.h68
-rw-r--r--protocols/Skype/src/skype_services.cpp46
-rw-r--r--protocols/Skype/src/skype_subclassing.cpp27
-rw-r--r--protocols/Skype/src/skype_subclassing.h4
-rw-r--r--protocols/Skype/src/skype_utils.cpp28
13 files changed, 393 insertions, 300 deletions
diff --git a/protocols/Skype/Skype_10.vcxproj.filters b/protocols/Skype/Skype_10.vcxproj.filters
index 1fad8dd6c5..ab6936b64a 100644
--- a/protocols/Skype/Skype_10.vcxproj.filters
+++ b/protocols/Skype/Skype_10.vcxproj.filters
@@ -105,11 +105,19 @@
</ResourceCompile>
</ItemGroup>
<ItemGroup>
- <None Include="res\Main.ico" />
- <None Include="res\auth_grant.ico" />
- <None Include="res\auth_request.ico" />
- <None Include="res\auth_revoke.ico" />
<None Include="..\..\..\SkypeKit\SDK\bin\windows-x86\windows-x86-skypekit.exe" />
<None Include="..\..\..\SkypeKit\keypair.bin" />
+ <None Include="res\auth_grant.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\auth_request.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\auth_revoke.ico">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="res\Main.ico">
+ <Filter>Resource Files</Filter>
+ </None>
</ItemGroup>
</Project> \ No newline at end of file
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;
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;
- 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;
- 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;
- 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;
+// 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"<m>%s</m>", ::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<char>(::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 <time.h>
-
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<FileTransfer> 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<CAccount, Account> 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