From 94e7b05c2151d15e46465aff01970853ef01e4db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20P=C3=B6sel?= Date: Sat, 3 Dec 2016 09:16:21 +0100 Subject: SkypeWeb: Fix disappearing status message (fixes #615) --- protocols/SkypeWeb/src/skype_proto.cpp | 705 +++++++++++++++++---------------- 1 file changed, 354 insertions(+), 351 deletions(-) (limited to 'protocols') diff --git a/protocols/SkypeWeb/src/skype_proto.cpp b/protocols/SkypeWeb/src/skype_proto.cpp index bed1e13ea3..8e4fa70045 100644 --- a/protocols/SkypeWeb/src/skype_proto.cpp +++ b/protocols/SkypeWeb/src/skype_proto.cpp @@ -1,352 +1,355 @@ -/* -Copyright (c) 2015-16 Miranda NG project (http://miranda-ng.org) - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation version 2 -of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include "stdafx.h" - -CSkypeProto::CSkypeProto(const char* protoName, const wchar_t* userName) : - PROTO(protoName, userName), - m_PopupClasses(1), - m_InviteDialogs(1), - m_GCCreateDialogs(1), - m_OutMessages(3, PtrKeySortT), - m_bThreadsTerminated(0), - m_TrouterConnection(0), - m_pollingConnection(0), - m_opts(this), - Contacts(this) -{ - InitNetwork(); - - requestQueue = new RequestQueue(m_hNetlibUser); - - CreateProtoService(PS_CREATEACCMGRUI, &CSkypeProto::OnAccountManagerInit); - CreateProtoService(PS_GETAVATARINFO, &CSkypeProto::SvcGetAvatarInfo); - CreateProtoService(PS_GETAVATARCAPS, &CSkypeProto::SvcGetAvatarCaps); - CreateProtoService(PS_GETMYAVATAR, &CSkypeProto::SvcGetMyAvatar); - CreateProtoService(PS_SETMYAVATAR, &CSkypeProto::SvcSetMyAvatar); - - CreateProtoService("/IncomingCallCLE", &CSkypeProto::OnIncomingCallCLE); - CreateProtoService("/IncomingCallPP", &CSkypeProto::OnIncomingCallPP); - - m_tszAvatarFolder = std::wstring(VARSW(L"%miranda_avatarcache%")) + L"\\" + m_tszUserName; - DWORD dwAttributes = GetFileAttributes(m_tszAvatarFolder.c_str()); - if (dwAttributes == 0xffffffff || (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) - CreateDirectoryTreeW(m_tszAvatarFolder.c_str()); - - //sounds - SkinAddNewSoundEx("skype_inc_call", "SkypeWeb", LPGEN("Incoming call sound")); - SkinAddNewSoundEx("skype_call_canceled", "SkypeWeb", LPGEN("Incoming call canceled sound")); - - SkypeSetTimer(); - - m_hPollingThread = ForkThreadEx(&CSkypeProto::PollingThread, NULL, NULL); - m_hTrouterThread = ForkThreadEx(&CSkypeProto::TRouterThread, NULL, NULL); -} - -CSkypeProto::~CSkypeProto() -{ - requestQueue->Stop(); - delete requestQueue; - - UnInitNetwork(); - UninitPopups(); - - if (m_hPollingThread) - { - TerminateThread(m_hPollingThread, NULL); - m_hPollingThread = NULL; - } - - if (m_hTrouterThread) - { - TerminateThread(m_hTrouterThread, NULL); - m_hTrouterThread = NULL; - } - - SkypeUnsetTimer(); -} - -int CSkypeProto::OnPreShutdown(WPARAM, LPARAM) -{ - debugLogA(__FUNCTION__); - - requestQueue->Stop(); - - m_bThreadsTerminated = true; - - m_hPollingEvent.Set(); - m_hTrouterEvent.Set(); - - return 0; -} - -DWORD_PTR CSkypeProto::GetCaps(int type, MCONTACT) -{ - switch (type) - { - case PFLAGNUM_1: - return PF1_IM | PF1_AUTHREQ | PF1_CHAT | PF1_BASICSEARCH | PF1_MODEMSG | PF1_FILE; - case PFLAGNUM_2: - return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_HEAVYDND; - case PFLAGNUM_3: - return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_HEAVYDND; - case PFLAGNUM_4: - return PF4_FORCEADDED | PF4_NOAUTHDENYREASON | PF4_SUPPORTTYPING | PF4_AVATARS | PF4_IMSENDOFFLINE | PF4_OFFLINEFILES; - case PFLAG_UNIQUEIDTEXT: - return (DWORD_PTR)Translate("Skypename"); - case PFLAG_UNIQUEIDSETTING: - return (DWORD_PTR)SKYPE_SETTINGS_ID; - } - return 0; -} - -int CSkypeProto::SetAwayMsg(int, const wchar_t *msg) -{ - PushRequest(new SetStatusMsgRequest(msg ? T2Utf(msg) : "", li)); - return 0; -} - -HANDLE CSkypeProto::GetAwayMsg(MCONTACT hContact) -{ - PushRequest(new GetProfileRequest(li, Contacts[hContact]), [this, hContact](const NETLIBHTTPREQUEST *response) - { - if (!response || !response->pData) - return; - - JSONNode root = JSONNode::parse(response->pData); - - if (JSONNode &mood = root["mood"]) - { - CMStringW str = mood.as_mstring(); - this->ProtoBroadcastAck(hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)1, (LPARAM)str.c_str()); - } - this->ProtoBroadcastAck(hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)1, 0); - }); - return (HANDLE)1; -} - -MCONTACT CSkypeProto::AddToList(int, PROTOSEARCHRESULT *psr) -{ - debugLogA(__FUNCTION__); - - if (psr->id.a == NULL) - return NULL; - MCONTACT hContact; - - if (psr->flags & PSR_UNICODE) - hContact = AddContact(T2Utf(psr->id.w)); - else - hContact = AddContact(psr->id.a); - - return hContact; -} - -MCONTACT CSkypeProto::AddToListByEvent(int, int, MEVENT hDbEvent) -{ - debugLogA(__FUNCTION__); - DBEVENTINFO dbei = { sizeof(dbei) }; - if ((dbei.cbBlob = db_event_getBlobSize(hDbEvent)) == (DWORD)(-1)) - return NULL; - if ((dbei.pBlob = (PBYTE)alloca(dbei.cbBlob)) == NULL) - return NULL; - if (db_event_get(hDbEvent, &dbei)) - return NULL; - if (mir_strcmp(dbei.szModule, m_szModuleName)) - return NULL; - if (dbei.eventType != EVENTTYPE_AUTHREQUEST) - return NULL; - - DB_AUTH_BLOB blob(dbei.pBlob); - - MCONTACT hContact = AddContact(ptrA(blob.get_id())); - return hContact; -} - -int CSkypeProto::Authorize(MEVENT hDbEvent) -{ - MCONTACT hContact = GetContactFromAuthEvent(hDbEvent); - if (hContact == INVALID_CONTACT_ID) - return 1; - - PushRequest(new AuthAcceptRequest(li, Contacts[hContact])); - return 0; -} - -int CSkypeProto::AuthDeny(MEVENT hDbEvent, const wchar_t*) -{ - MCONTACT hContact = GetContactFromAuthEvent(hDbEvent); - if (hContact == INVALID_CONTACT_ID) - return 1; - - PushRequest(new AuthDeclineRequest(li, Contacts[hContact])); - return 0; -} - -int CSkypeProto::AuthRecv(MCONTACT, PROTORECVEVENT* pre) -{ - return Proto_AuthRecv(m_szModuleName, pre); -} - -int CSkypeProto::AuthRequest(MCONTACT hContact, const wchar_t *szMessage) -{ - if (hContact == INVALID_CONTACT_ID) - return 1; - - PushRequest(new AddContactRequest(li, Contacts[hContact], T2Utf(szMessage))); - return 0; -} - -int CSkypeProto::GetInfo(MCONTACT hContact, int) -{ - if (!isChatRoom(hContact)) - PushRequest( - new GetProfileRequest(li, Contacts[hContact]), - &CSkypeProto::LoadProfile); - return 0; -} - -int CSkypeProto::SendMsg(MCONTACT hContact, int flags, const char *msg) -{ - return OnSendMessage(hContact, flags, msg); -} - -int CSkypeProto::SetStatus(int iNewStatus) -{ - if (iNewStatus == m_iDesiredStatus) - return 0; - - switch (iNewStatus) - { - case ID_STATUS_FREECHAT: - case ID_STATUS_ONTHEPHONE: - iNewStatus = ID_STATUS_ONLINE; - break; - - case ID_STATUS_NA: - case ID_STATUS_OUTTOLUNCH: - iNewStatus = ID_STATUS_AWAY; - break; - - case ID_STATUS_OCCUPIED: - iNewStatus = ID_STATUS_DND; - break; - } - - //mir_cslock lck(m_StatusLock); - - debugLogA(__FUNCTION__ ": changing status from %i to %i", m_iStatus, iNewStatus); - - int old_status = m_iStatus; - m_iDesiredStatus = iNewStatus; - - if (iNewStatus == ID_STATUS_OFFLINE) - { - if (m_iStatus > ID_STATUS_CONNECTING + 1) - { - SendRequest(new DeleteEndpointRequest(li)); - } - m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; - // logout - requestQueue->Stop(); - - CloseDialogs(); - ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, ID_STATUS_OFFLINE); - - if (!Miranda_IsTerminated()) - SetAllContactsStatus(ID_STATUS_OFFLINE); - return 0; - } - else - { - if (old_status == ID_STATUS_CONNECTING) - return 0; - - if (old_status == ID_STATUS_OFFLINE && m_iStatus == ID_STATUS_OFFLINE) - { - Login(); - } - else - { - SendRequest(new SetStatusRequest(MirandaToSkypeStatus(m_iDesiredStatus), li), &CSkypeProto::OnStatusChanged); - } - } - - ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); - return 0; -} - -int CSkypeProto::UserIsTyping(MCONTACT hContact, int type) -{ - SendRequest(new SendTypingRequest(Contacts[hContact], type, li)); - return 0; -} - -int CSkypeProto::OnEvent(PROTOEVENTTYPE iEventType, WPARAM wParam, LPARAM lParam) -{ - switch (iEventType) - { - case EV_PROTO_ONLOAD: - return OnAccountLoaded(wParam, lParam); - - case EV_PROTO_ONCONTACTDELETED: - return OnContactDeleted(wParam, lParam); - - case EV_PROTO_ONMENU: - return OnInitStatusMenu(); - - case EV_PROTO_ONEXIT: - return OnPreShutdown(wParam, lParam); - } - - return 1; -} - -int CSkypeProto::RecvContacts(MCONTACT hContact, PROTORECVEVENT* pre) -{ - PROTOSEARCHRESULT **isrList = (PROTOSEARCHRESULT**)pre->szMessage; - DWORD cbBlob = 0; - BYTE *pBlob; - BYTE *pCurBlob; - int i; - - int nCount = *((LPARAM*)pre->lParam); - char* szMessageId = ((char*)pre->lParam + sizeof(LPARAM)); - - //if (GetMessageFromDb(hContact, szMessageId, pre->timestamp)) return 0; - - for (i = 0; i < nCount; i++) - cbBlob += int(/*mir_wstrlen(isrList[i]->nick.w)*/0 + 2 + mir_wstrlen(isrList[i]->id.w) + mir_strlen(szMessageId)); - - pBlob = (PBYTE)mir_calloc(cbBlob); - - for (i = 0, pCurBlob = pBlob; i < nCount; i++) - { - //mir_strcpy((char*)pCurBlob, _T2A(isrList[i]->nick.w)); - pCurBlob += mir_strlen((PCHAR)pCurBlob) + 1; - - mir_strcpy((char*)pCurBlob, _T2A(isrList[i]->id.w)); - pCurBlob += mir_strlen((char*)pCurBlob) + 1; - } - - //memcpy(pCurBlob + 1, szMessageId, mir_strlen(szMessageId)); - - AddEventToDb(hContact, EVENTTYPE_CONTACTS, pre->timestamp, (pre->flags & PREF_CREATEREAD) ? DBEF_READ : 0, cbBlob, pBlob); - - mir_free(pBlob); - - return 0; +/* +Copyright (c) 2015-16 Miranda NG project (http://miranda-ng.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation version 2 +of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include "stdafx.h" + +CSkypeProto::CSkypeProto(const char* protoName, const wchar_t* userName) : + PROTO(protoName, userName), + m_PopupClasses(1), + m_InviteDialogs(1), + m_GCCreateDialogs(1), + m_OutMessages(3, PtrKeySortT), + m_bThreadsTerminated(0), + m_TrouterConnection(0), + m_pollingConnection(0), + m_opts(this), + Contacts(this) +{ + InitNetwork(); + + requestQueue = new RequestQueue(m_hNetlibUser); + + CreateProtoService(PS_CREATEACCMGRUI, &CSkypeProto::OnAccountManagerInit); + CreateProtoService(PS_GETAVATARINFO, &CSkypeProto::SvcGetAvatarInfo); + CreateProtoService(PS_GETAVATARCAPS, &CSkypeProto::SvcGetAvatarCaps); + CreateProtoService(PS_GETMYAVATAR, &CSkypeProto::SvcGetMyAvatar); + CreateProtoService(PS_SETMYAVATAR, &CSkypeProto::SvcSetMyAvatar); + + CreateProtoService("/IncomingCallCLE", &CSkypeProto::OnIncomingCallCLE); + CreateProtoService("/IncomingCallPP", &CSkypeProto::OnIncomingCallPP); + + m_tszAvatarFolder = std::wstring(VARSW(L"%miranda_avatarcache%")) + L"\\" + m_tszUserName; + DWORD dwAttributes = GetFileAttributes(m_tszAvatarFolder.c_str()); + if (dwAttributes == 0xffffffff || (dwAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) + CreateDirectoryTreeW(m_tszAvatarFolder.c_str()); + + //sounds + SkinAddNewSoundEx("skype_inc_call", "SkypeWeb", LPGEN("Incoming call sound")); + SkinAddNewSoundEx("skype_call_canceled", "SkypeWeb", LPGEN("Incoming call canceled sound")); + + SkypeSetTimer(); + + m_hPollingThread = ForkThreadEx(&CSkypeProto::PollingThread, NULL, NULL); + m_hTrouterThread = ForkThreadEx(&CSkypeProto::TRouterThread, NULL, NULL); +} + +CSkypeProto::~CSkypeProto() +{ + requestQueue->Stop(); + delete requestQueue; + + UnInitNetwork(); + UninitPopups(); + + if (m_hPollingThread) + { + TerminateThread(m_hPollingThread, NULL); + m_hPollingThread = NULL; + } + + if (m_hTrouterThread) + { + TerminateThread(m_hTrouterThread, NULL); + m_hTrouterThread = NULL; + } + + SkypeUnsetTimer(); +} + +int CSkypeProto::OnPreShutdown(WPARAM, LPARAM) +{ + debugLogA(__FUNCTION__); + + requestQueue->Stop(); + + m_bThreadsTerminated = true; + + m_hPollingEvent.Set(); + m_hTrouterEvent.Set(); + + return 0; +} + +DWORD_PTR CSkypeProto::GetCaps(int type, MCONTACT) +{ + switch (type) + { + case PFLAGNUM_1: + return PF1_IM | PF1_AUTHREQ | PF1_CHAT | PF1_BASICSEARCH | PF1_MODEMSG | PF1_FILE; + case PFLAGNUM_2: + return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_HEAVYDND; + case PFLAGNUM_3: + return PF2_ONLINE | PF2_INVISIBLE | PF2_SHORTAWAY | PF2_HEAVYDND; + case PFLAGNUM_4: + return PF4_FORCEADDED | PF4_NOAUTHDENYREASON | PF4_SUPPORTTYPING | PF4_AVATARS | PF4_IMSENDOFFLINE | PF4_OFFLINEFILES; + case PFLAG_UNIQUEIDTEXT: + return (DWORD_PTR)Translate("Skypename"); + case PFLAG_UNIQUEIDSETTING: + return (DWORD_PTR)SKYPE_SETTINGS_ID; + } + return 0; +} + +int CSkypeProto::SetAwayMsg(int, const wchar_t *msg) +{ + PushRequest(new SetStatusMsgRequest(msg ? T2Utf(msg) : "", li)); + return 0; +} + +HANDLE CSkypeProto::GetAwayMsg(MCONTACT hContact) +{ + PushRequest(new GetProfileRequest(li, Contacts[hContact]), [this, hContact](const NETLIBHTTPREQUEST *response) + { + if (!response || !response->pData) + return; + + JSONNode root = JSONNode::parse(response->pData); + + if (JSONNode &mood = root["mood"]) + { + CMStringW str = mood.as_mstring(); + this->ProtoBroadcastAck(hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)1, (LPARAM)str.c_str()); + } + else + { + this->ProtoBroadcastAck(hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, (HANDLE)1, 0); + } + }); + return (HANDLE)1; +} + +MCONTACT CSkypeProto::AddToList(int, PROTOSEARCHRESULT *psr) +{ + debugLogA(__FUNCTION__); + + if (psr->id.a == NULL) + return NULL; + MCONTACT hContact; + + if (psr->flags & PSR_UNICODE) + hContact = AddContact(T2Utf(psr->id.w)); + else + hContact = AddContact(psr->id.a); + + return hContact; +} + +MCONTACT CSkypeProto::AddToListByEvent(int, int, MEVENT hDbEvent) +{ + debugLogA(__FUNCTION__); + DBEVENTINFO dbei = { sizeof(dbei) }; + if ((dbei.cbBlob = db_event_getBlobSize(hDbEvent)) == (DWORD)(-1)) + return NULL; + if ((dbei.pBlob = (PBYTE)alloca(dbei.cbBlob)) == NULL) + return NULL; + if (db_event_get(hDbEvent, &dbei)) + return NULL; + if (mir_strcmp(dbei.szModule, m_szModuleName)) + return NULL; + if (dbei.eventType != EVENTTYPE_AUTHREQUEST) + return NULL; + + DB_AUTH_BLOB blob(dbei.pBlob); + + MCONTACT hContact = AddContact(ptrA(blob.get_id())); + return hContact; +} + +int CSkypeProto::Authorize(MEVENT hDbEvent) +{ + MCONTACT hContact = GetContactFromAuthEvent(hDbEvent); + if (hContact == INVALID_CONTACT_ID) + return 1; + + PushRequest(new AuthAcceptRequest(li, Contacts[hContact])); + return 0; +} + +int CSkypeProto::AuthDeny(MEVENT hDbEvent, const wchar_t*) +{ + MCONTACT hContact = GetContactFromAuthEvent(hDbEvent); + if (hContact == INVALID_CONTACT_ID) + return 1; + + PushRequest(new AuthDeclineRequest(li, Contacts[hContact])); + return 0; +} + +int CSkypeProto::AuthRecv(MCONTACT, PROTORECVEVENT* pre) +{ + return Proto_AuthRecv(m_szModuleName, pre); +} + +int CSkypeProto::AuthRequest(MCONTACT hContact, const wchar_t *szMessage) +{ + if (hContact == INVALID_CONTACT_ID) + return 1; + + PushRequest(new AddContactRequest(li, Contacts[hContact], T2Utf(szMessage))); + return 0; +} + +int CSkypeProto::GetInfo(MCONTACT hContact, int) +{ + if (!isChatRoom(hContact)) + PushRequest( + new GetProfileRequest(li, Contacts[hContact]), + &CSkypeProto::LoadProfile); + return 0; +} + +int CSkypeProto::SendMsg(MCONTACT hContact, int flags, const char *msg) +{ + return OnSendMessage(hContact, flags, msg); +} + +int CSkypeProto::SetStatus(int iNewStatus) +{ + if (iNewStatus == m_iDesiredStatus) + return 0; + + switch (iNewStatus) + { + case ID_STATUS_FREECHAT: + case ID_STATUS_ONTHEPHONE: + iNewStatus = ID_STATUS_ONLINE; + break; + + case ID_STATUS_NA: + case ID_STATUS_OUTTOLUNCH: + iNewStatus = ID_STATUS_AWAY; + break; + + case ID_STATUS_OCCUPIED: + iNewStatus = ID_STATUS_DND; + break; + } + + //mir_cslock lck(m_StatusLock); + + debugLogA(__FUNCTION__ ": changing status from %i to %i", m_iStatus, iNewStatus); + + int old_status = m_iStatus; + m_iDesiredStatus = iNewStatus; + + if (iNewStatus == ID_STATUS_OFFLINE) + { + if (m_iStatus > ID_STATUS_CONNECTING + 1) + { + SendRequest(new DeleteEndpointRequest(li)); + } + m_iStatus = m_iDesiredStatus = ID_STATUS_OFFLINE; + // logout + requestQueue->Stop(); + + CloseDialogs(); + ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, ID_STATUS_OFFLINE); + + if (!Miranda_IsTerminated()) + SetAllContactsStatus(ID_STATUS_OFFLINE); + return 0; + } + else + { + if (old_status == ID_STATUS_CONNECTING) + return 0; + + if (old_status == ID_STATUS_OFFLINE && m_iStatus == ID_STATUS_OFFLINE) + { + Login(); + } + else + { + SendRequest(new SetStatusRequest(MirandaToSkypeStatus(m_iDesiredStatus), li), &CSkypeProto::OnStatusChanged); + } + } + + ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)old_status, m_iStatus); + return 0; +} + +int CSkypeProto::UserIsTyping(MCONTACT hContact, int type) +{ + SendRequest(new SendTypingRequest(Contacts[hContact], type, li)); + return 0; +} + +int CSkypeProto::OnEvent(PROTOEVENTTYPE iEventType, WPARAM wParam, LPARAM lParam) +{ + switch (iEventType) + { + case EV_PROTO_ONLOAD: + return OnAccountLoaded(wParam, lParam); + + case EV_PROTO_ONCONTACTDELETED: + return OnContactDeleted(wParam, lParam); + + case EV_PROTO_ONMENU: + return OnInitStatusMenu(); + + case EV_PROTO_ONEXIT: + return OnPreShutdown(wParam, lParam); + } + + return 1; +} + +int CSkypeProto::RecvContacts(MCONTACT hContact, PROTORECVEVENT* pre) +{ + PROTOSEARCHRESULT **isrList = (PROTOSEARCHRESULT**)pre->szMessage; + DWORD cbBlob = 0; + BYTE *pBlob; + BYTE *pCurBlob; + int i; + + int nCount = *((LPARAM*)pre->lParam); + char* szMessageId = ((char*)pre->lParam + sizeof(LPARAM)); + + //if (GetMessageFromDb(hContact, szMessageId, pre->timestamp)) return 0; + + for (i = 0; i < nCount; i++) + cbBlob += int(/*mir_wstrlen(isrList[i]->nick.w)*/0 + 2 + mir_wstrlen(isrList[i]->id.w) + mir_strlen(szMessageId)); + + pBlob = (PBYTE)mir_calloc(cbBlob); + + for (i = 0, pCurBlob = pBlob; i < nCount; i++) + { + //mir_strcpy((char*)pCurBlob, _T2A(isrList[i]->nick.w)); + pCurBlob += mir_strlen((PCHAR)pCurBlob) + 1; + + mir_strcpy((char*)pCurBlob, _T2A(isrList[i]->id.w)); + pCurBlob += mir_strlen((char*)pCurBlob) + 1; + } + + //memcpy(pCurBlob + 1, szMessageId, mir_strlen(szMessageId)); + + AddEventToDb(hContact, EVENTTYPE_CONTACTS, pre->timestamp, (pre->flags & PREF_CREATEREAD) ? DBEF_READ : 0, cbBlob, pBlob); + + mir_free(pBlob); + + return 0; } \ No newline at end of file -- cgit v1.2.3