MEVENT CSkypeProto::AppendDBEvent(MCONTACT hContact, MEVENT hEvent, const char *szContent, const char *szUid, time_t edit_time) { mir_cslock lck(m_AppendMessageLock); DBEVENTINFO dbei = { sizeof(dbei) }; dbei.cbBlob = db_event_getBlobSize(hEvent); dbei.pBlob = mir_ptr<BYTE>((PBYTE)mir_alloc(dbei.cbBlob)); db_event_get(hEvent, &dbei); JSONNode jMsg = JSONNode::parse((char*)dbei.pBlob); if (jMsg) { JSONNode &jEdits = jMsg["edits"]; if (jEdits) { for (auto it = jEdits.begin(); it != jEdits.end(); ++it) { const JSONNode &jEdit = *it; if (jEdit["time"].as_int() == edit_time) return hEvent; } JSONNode jEdit; jEdit << JSONNode("time", (long)edit_time) << JSONNode("text", szContent); jEdits << jEdit; } } else { jMsg = JSONNode(); JSONNode jOriginalMsg; jOriginalMsg.set_name("original_message"); JSONNode jEdits(JSON_ARRAY); jEdits.set_name("edits"); JSONNode jEdit; jOriginalMsg << JSONNode("time", (long)dbei.timestamp) << JSONNode("text", (char*)dbei.pBlob); jMsg << jOriginalMsg; jEdit << JSONNode("time", (long)edit_time) << JSONNode("text", szContent); jEdits << jEdit; jMsg << jEdits; } db_event_delete(hContact, hEvent); return AddDbEvent(SKYPE_DB_EVENT_TYPE_EDITED_MESSAGE, hContact, dbei.timestamp, DBEF_UTF, jMsg.write().c_str(), szUid); }
void CSkypeProto::OnTrouterEvent(const JSONNode &body, const JSONNode &) { //std::string displayname = body["displayName"].as_string(); //std::string cuid = body["callerId"].as_string(); std::string uid = body["conversationId"].as_string(); std::string gp = body["gp"].as_string(); int evt = body["evt"].as_int(); switch (evt) { case 100: //incoming call { std::string callId = body["convoCallId"].as_string(); if (!uid.empty()) { MCONTACT hContact = AddContact(uid.c_str(), true); MEVENT hEvent = AddDbEvent(SKYPE_DB_EVENT_TYPE_INCOMING_CALL, hContact, time(NULL), DBEF_READ, gp.c_str(), callId.c_str()); SkinPlaySound("skype_inc_call"); CLISTEVENT cle = { sizeof(cle) }; cle.flags |= CLEF_TCHAR; cle.hContact = hContact; cle.hDbEvent = hEvent; cle.lParam = SKYPE_DB_EVENT_TYPE_INCOMING_CALL; cle.hIcon = IcoLib_GetIconByHandle(GetIconHandle("inc_call")); CMStringA service(FORMAT, "%s/IncomingCallCLE", GetContactProto(hContact)); cle.pszService = service.GetBuffer(); CMString tooltip(FORMAT, TranslateT("Incoming call from %s"), pcli->pfnGetContactDisplayName(hContact, 0)); cle.ptszTooltip = tooltip.GetBuffer(); CallService(MS_CLIST_ADDEVENT, 0, (LPARAM)&cle); ShowNotification(pcli->pfnGetContactDisplayName(hContact, 0), TranslateT("Incoming call"), hContact, SKYPE_DB_EVENT_TYPE_INCOMING_CALL); } } break; case 104: //call canceled: callerId=""; conversationId=NULL; callId=call id // std::string callId = body["callId"].as_string(); SkinPlaySound("skype_call_canceled"); break; } }
void CSkypeProto::OnGetServerHistory(const NETLIBHTTPREQUEST *response) { if (response == NULL) return; JSONNode root = JSONNode::parse(response->pData); if (!root) return; const JSONNode &metadata = root["_metadata"]; const JSONNode &conversations = root["messages"].as_array(); int totalCount = metadata["totalCount"].as_int(); std::string syncState = metadata["syncState"].as_string(); bool markAllAsUnread = getBool("MarkMesUnread", true); if (totalCount >= 99 || conversations.size() >= 99) PushRequest(new GetHistoryOnUrlRequest(syncState.c_str(), li), &CSkypeProto::OnGetServerHistory); for (int i = (int)conversations.size(); i >= 0; i--) { const JSONNode &message = conversations.at(i); CMStringA szMessageId = message["clientmessageid"] ? message["clientmessageid"].as_string().c_str() : message["skypeeditedid"].as_string().c_str(); std::string messageType = message["messagetype"].as_string(); std::string from = message["from"].as_string(); std::string content = message["content"].as_string(); std::string conversationLink = message["conversationLink"].as_string(); int emoteOffset = message["skypeemoteoffset"].as_int(); time_t timestamp = IsoToUnixTime(message["composetime"].as_string().c_str()); CMStringA skypename(UrlToSkypename(from.c_str())); bool isEdited = message["skypeeditedid"]; MCONTACT hContact = FindContact(UrlToSkypename(conversationLink.c_str())); if (timestamp > db_get_dw(hContact, m_szModuleName, "LastMsgTime", 0)) db_set_dw(hContact, m_szModuleName, "LastMsgTime", (DWORD)timestamp); int iFlags = DBEF_UTF; if (!markAllAsUnread) iFlags |= DBEF_READ; if (IsMe(skypename)) iFlags |= DBEF_SENT; if (strstr(conversationLink.c_str(), "/8:")) { if (messageType == "Text" || messageType == "RichText") { ptrA szMessage(messageType == "RichText" ? RemoveHtml(content.c_str()) : mir_strdup(content.c_str())); MEVENT dbevent = GetMessageFromDb(hContact, szMessageId); if (isEdited && dbevent != NULL) { AppendDBEvent(hContact, dbevent, szMessage, szMessageId, timestamp); } else AddDbEvent(emoteOffset == 0 ? EVENTTYPE_MESSAGE : SKYPE_DB_EVENT_TYPE_ACTION, hContact, timestamp, iFlags, &szMessage[emoteOffset], szMessageId); } else if (messageType == "Event/Call") { AddDbEvent(SKYPE_DB_EVENT_TYPE_CALL_INFO, hContact, timestamp, iFlags, content.c_str(), szMessageId); } else if (messageType == "RichText/Files") { AddDbEvent(SKYPE_DB_EVENT_TYPE_FILETRANSFER_INFO, hContact, timestamp, iFlags, content.c_str(), szMessageId); } else if (messageType == "RichText/UriObject") { AddDbEvent(SKYPE_DB_EVENT_TYPE_URIOBJ, hContact, timestamp, iFlags, content.c_str(), szMessageId); } else if (messageType == "RichText/Contacts") { ProcessContactRecv(hContact, timestamp, content.c_str(), szMessageId); } else { AddDbEvent(SKYPE_DB_EVENT_TYPE_UNKNOWN, hContact, timestamp, iFlags, content.c_str(), szMessageId); } } else if (conversationLink.find("/19:") != -1) { CMStringA chatname(UrlToSkypename(conversationLink.c_str())); if (messageType == "Text" || messageType == "RichText") { AddMessageToChat(_A2T(chatname), _A2T(skypename), content.c_str(), emoteOffset != NULL, emoteOffset, timestamp, true); } } } }