summaryrefslogtreecommitdiff
path: root/protocols/Skype/src/skype_database.cpp
blob: 9ed2a217971f944b954aa641bcdaada088ecf04b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include "skype_proto.h"

bool CSkypeProto::IsMessageInDB(HANDLE hContact, DWORD timestamp, const char* guid, int flag)
{
	bool result = false;

	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)
		{
			if (::memcmp(&dbei.pBlob[dbei.cbBlob - 32], guid, 32) == 0)
			{
				::mir_free(dbei.pBlob);
				result = true;
				break;
			}
		}

		::mir_free(dbei.pBlob);
		hDbEvent = ::db_event_prev(hDbEvent);
	}

	return result;
}

HANDLE CSkypeProto::AddDBEvent(HANDLE hContact, WORD type, DWORD timestamp, DWORD flags, DWORD cbBlob, PBYTE pBlob)
{
	DBEVENTINFO dbei = { 0 };
	dbei.cbSize = sizeof(dbei);
	dbei.szModule = this->m_szModuleName;
	dbei.timestamp = timestamp;
	dbei.eventType = type;
	dbei.cbBlob = cbBlob;
	dbei.pBlob = pBlob;
	dbei.flags = flags;

	return ::db_event_add(hContact, &dbei);
}

void CSkypeProto::RaiseAuthRequestEvent(DWORD timestamp, CContact::Ref contact)
{
	char *sid = ::mir_strdup(contact->GetSid());
	char *nick = ::mir_strdup(contact->GetNick());

	SEString data;

	contact->GetPropReceivedAuthrequest(data);
	char* reason = ::mir_strdup(data);

	SEString last;
	contact->GetFullname(data, last);
	char* firstName = ::mir_strdup(data);
	char* lastName = ::mir_strdup(last);

	HANDLE hContact = this->AddContact(contact);

	/*blob is: 0(DWORD), hContact(DWORD), nick(ASCIIZ), firstName(ASCIIZ), lastName(ASCIIZ), sid(ASCIIZ), reason(ASCIIZ)*/
	DWORD cbBlob = (DWORD)
		(sizeof(DWORD) * 2 + 
		::strlen(nick) + 
		::strlen(firstName) + 
		::strlen(lastName) + 
		::strlen(sid) + 
		::strlen(reason) + 
		5);

	PBYTE pBlob, pCurBlob;
	pCurBlob = pBlob = (PBYTE)::mir_alloc(cbBlob);

	*((PDWORD)pCurBlob) = 0; pCurBlob += sizeof(DWORD);
	*((PDWORD)pCurBlob) = (DWORD)hContact; pCurBlob += sizeof(DWORD);
	::strcpy((char*)pCurBlob, nick); pCurBlob += ::strlen(nick) + 1;
	::strcpy((char*)pCurBlob, firstName); pCurBlob += ::strlen(firstName) + 1;
	::strcpy((char*)pCurBlob, lastName); pCurBlob += ::strlen(lastName) + 1;
	::strcpy((char*)pCurBlob, sid); pCurBlob += ::strlen(sid) + 1;
	::strcpy((char*)pCurBlob, reason);

	this->AddDBEvent(hContact, EVENTTYPE_AUTHREQUEST, time(NULL), PREF_UTF, cbBlob, pBlob);
}

void CSkypeProto::RaiseMessageReceivedEvent(HANDLE hContact, DWORD timestamp, const char *guid, const wchar_t *message, bool isNeedCheck)
{
	if (isNeedCheck)
		if (this->IsMessageInDB(hContact, timestamp, guid))
			return;

	PROTORECVEVENT recv;
	recv.flags = PREF_UTF;
	recv.lParam = (LPARAM)guid;
	recv.timestamp = timestamp;
	recv.szMessage = ::mir_utf8encodeW(message);

	::ProtoChainRecvMsg(hContact, &recv);
}

void CSkypeProto::RaiseMessageSendedEvent(HANDLE hContact, DWORD timestamp, const char *guid, const wchar_t *message)
{
	if (this->IsMessageInDB(hContact, timestamp, guid, DBEF_SENT))
		return;

	int guidLen = ::strlen(guid);

	char *msg = ::mir_utf8encodeW(message);
	int  msgLen = ::strlen(msg) + 1;

	msg = (char *)::mir_realloc(msg, msgLen + 32);
	::memcpy((char *)&msg[msgLen], guid, 32);

	this->AddDBEvent(hContact, EVENTTYPE_MESSAGE, timestamp, PREF_UTF | DBEF_SENT, msgLen + guidLen, (PBYTE)msg);
}