bool parse_clientlogin_response(NETLIBHTTPREQUEST *nlhr, NETLIBHTTPHEADER *my_headers, CMStringA &token, CMStringA &secret, time_t &hosttime) { //TODO: validate response //TODO: return false on errors //TODO: extract token, secret, hosttime from response int datalen = 0; for (int i = 0; i < nlhr->headersCount; i++) { if (!mir_strcmp(nlhr->headers[i].szName, "Set-Cookie")) { my_headers[0].szName = "Cookie"; my_headers[0].szValue = mir_strdup(nlhr->headers[i].szValue); } } ptrW buf_w(mir_utf8decodeW(nlhr->pData)); HXML root = xmlParseString(buf_w, &datalen, _T("")); if (!root) return false; HXML status = xmlGetChildByPath(root, _T("response/statusCode"), 0); if (!status) return false; LPCTSTR status_text = xmlGetText(status); // TODO: check other than 200 codes and print some debug info on errors if (wcscmp(status_text, L"200")) return false; HXML secret_node = xmlGetChildByPath(root, _T("response/data/sessionSecret"), 0); HXML hosttime_node = xmlGetChildByPath(root, _T("response/data/hostTime"), 0); if (!secret_node || !hosttime_node) return false; HXML token_node = xmlGetChildByPath(root, _T("response/data/token/a"), 0); if (!token_node) return false; LPCTSTR secret_w = xmlGetText(secret_node), token_w = xmlGetText(token_node), hosttime_w = xmlGetText(hosttime_node); if (!secret_w || !token_w || !hosttime_w) return false; secret = _T2A(secret_w); token = _T2A(token_w); hosttime = strtol(_T2A(hosttime_w), NULL, 10); return true; }
bool parse_start_socar_session_response(const char *response, CMStringA &bos_host, unsigned short &bos_port, CMStringA &cookie, CMStringA &tls_cert_name, bool encryption = true) { //TODO: extract bos_host, bos_port, cookie, tls_cert_name int datalen = 0; ptrW buf_w(mir_utf8decodeW(response)); HXML root = xmlParseString(buf_w, &datalen, _T("")); if (!root) return false; HXML status = xmlGetChildByPath(root, _T("response/statusCode"), 0); if (!status) return false; LPCTSTR status_text = xmlGetText(status); //TODO: check other than 200 codes and print some debug info on errors if (wcscmp(status_text, L"200")) return false; HXML host_node = xmlGetChildByPath(root, _T("response/data/host"), 0); HXML port_node = xmlGetChildByPath(root, _T("response/data/port"), 0); HXML cookie_node = xmlGetChildByPath(root, _T("response/data/cookie"), 0); if (!host_node || !port_node || !cookie_node) return false; LPCTSTR host_w = xmlGetText(host_node), port_w = xmlGetText(port_node), cookie_w = xmlGetText(cookie_node); if (!host_w || !port_w || !cookie_w) return false; bos_host = _T2A(host_w); bos_port = atoi(_T2A(port_w)); cookie = _T2A(cookie_w); if (encryption) { HXML tls_node = xmlGetChildByPath(root, _T("response/data/tlsCertName"), 0); //tls is optional, so this is not fatal error if (tls_node) { LPCTSTR certname_w = xmlGetText(tls_node); if (certname_w) tls_cert_name = _T2A(certname_w); } } return true; }
INT_PTR CSkypeProto::GetEventText(WPARAM, LPARAM lParam) { DBEVENTGETTEXT *pEvent = (DBEVENTGETTEXT *)lParam; CMStringA szText; BOOL bUseBB = db_get_b(NULL, pEvent->dbei->szModule, "UseBBCodes", 1); switch (pEvent->dbei->eventType) { case SKYPE_DB_EVENT_TYPE_EDITED_MESSAGE: { JSONNode jMsg = JSONNode::parse((char*)pEvent->dbei->pBlob); if (jMsg) { JSONNode &jOriginalMsg = jMsg["original_message"]; szText.AppendFormat(bUseBB ? Translate("[b]Original message:[/b]\n%s\n") : Translate("Original message:\n%s\n"), mir_utf8decodeA(jOriginalMsg["text"].as_string().c_str())); JSONNode &jEdits = jMsg["edits"]; for (auto it = jEdits.begin(); it != jEdits.end(); ++it) { const JSONNode &jEdit = *it; time_t time = jEdit["time"].as_int(); char szTime[MAX_PATH]; strftime(szTime, sizeof(szTime), "%X %x", localtime(&time)); szText.AppendFormat(bUseBB ? Translate("[b]Edited at %s:[/b]\n%s\n") : Translate("Edited at %s:\n%s\n"), szTime, mir_utf8decodeA(jEdit["text"].as_string().c_str())); } } else { szText = INVALID_DATA; } break; } case SKYPE_DB_EVENT_TYPE_CALL_INFO: { HXML xml = xmlParseString(ptrT(mir_utf8decodeT((char*)pEvent->dbei->pBlob)), 0, _T("partlist")); if (xml != NULL) { ptrA type(mir_t2a(xmlGetAttrValue(xml, _T("type")))); bool bType = (!mir_strcmpi(type, "started")) ? 1 : 0; time_t callDuration = 0; for (int i = 0; i < xmlGetChildCount(xml); i++) { HXML xmlPart = xmlGetNthChild(xml, _T("part"), i); if (xmlPart != NULL) { HXML xmlDuration = xmlGetChildByPath(xmlPart, _T("duration"), 0); if (xmlDuration != NULL) { callDuration = _ttol(xmlGetText(xmlDuration)); xmlDestroyNode(xmlDuration); xmlDestroyNode(xmlPart); break; } xmlDestroyNode(xmlPart); } } if (bType) { szText = Translate("Call"); } else { if (callDuration == 0) { szText = Translate("Call missed"); } else { char szTime[100]; strftime(szTime, sizeof(szTime), "%X", gmtime(&callDuration)); szText.Format(Translate("Call ended (%s)"), szTime); } } xmlDestroyNode(xml); } else { szText = INVALID_DATA; } break; } case SKYPE_DB_EVENT_TYPE_FILETRANSFER_INFO: { HXML xml = xmlParseString(ptrT(mir_utf8decodeT((char*)pEvent->dbei->pBlob)), 0, _T("files")); if (xml != NULL) { for (int i = 0; i < xmlGetChildCount(xml); i++) { LONGLONG fileSize = 0; HXML xmlNode = xmlGetNthChild(xml, _T("file"), i); if (xmlNode != NULL) { fileSize = _ttol(xmlGetAttrValue(xmlNode, _T("size"))); char *fileName = _T2A(xmlGetText(xmlNode)); if (fileName != NULL) { szText.AppendFormat(Translate("File transfer:\n\tFile name: %s \n\tSize: %lld bytes \n"), fileName, fileSize); } xmlDestroyNode(xmlNode); } } xmlDestroyNode(xml); } else { szText = INVALID_DATA; } break; } case SKYPE_DB_EVENT_TYPE_MOJI: case SKYPE_DB_EVENT_TYPE_URIOBJ: { HXML xml = xmlParseString(ptrT(mir_utf8decodeT((char*)pEvent->dbei->pBlob)), 0, _T("URIObject")); if (xml != NULL) { szText.Append(_T2A(xmlGetText(xml))); HXML xmlA = xmlGetChildByPath(xml, _T("a"), 0); if (xmlA != NULL) { szText += _T2A(xmlGetAttrValue(xmlA, _T("href"))); xmlDestroyNode(xmlA); } xmlDestroyNode(xml); } else { szText = INVALID_DATA; } break; } case SKYPE_DB_EVENT_TYPE_INCOMING_CALL: { szText = Translate("Incoming call"); break; } case SKYPE_DB_EVENT_TYPE_UNKNOWN: { szText.Format(Translate("Unknown event, please send this text for developer: \"%s\""), mir_utf8decodeA((char*)pEvent->dbei->pBlob)); break; } default: { szText = ptrA(mir_utf8decodeA((char*)pEvent->dbei->pBlob)); } } switch(pEvent->datatype) { case DBVT_TCHAR: { return (INT_PTR)mir_a2t(szText); } case DBVT_ASCIIZ: { return (INT_PTR)szText.Detach(); } case DBVT_UTF8: { return (INT_PTR)mir_utf8encode(szText); } default: { return NULL; } } }
void CSkypeProto::OnChatEvent(const JSONNode &node) { //std::string clientMsgId = node["clientmessageid"].as_string(); //std::string skypeEditedId = node["skypeeditedid"].as_string(); std::string fromLink = node["from"].as_string(); CMStringA from(ContactUrlToName(fromLink.c_str())); time_t timestamp = IsoToUnixTime(node["composetime"].as_string().c_str()); std::string content = node["content"].as_string(); int emoteOffset = node["skypeemoteoffset"].as_int(); std::string conversationLink = node["conversationLink"].as_string(); CMStringA chatname(ChatUrlToName(conversationLink.c_str())); CMString topic(node["threadtopic"].as_mstring()); if (FindChatRoom(chatname) == NULL) SendRequest(new GetChatInfoRequest(m_szRegToken, chatname, m_szServer), &CSkypeProto::OnGetChatInfo, topic.Detach()); std::string messageType = node["messagetype"].as_string(); if (!mir_strcmpi(messageType.c_str(), "Text") || !mir_strcmpi(messageType.c_str(), "RichText")) { AddMessageToChat(_A2T(chatname), _A2T(from), content.c_str(), emoteOffset != NULL, emoteOffset, timestamp); } else if (!mir_strcmpi(messageType.c_str(), "ThreadActivity/AddMember")) { ptrA xinitiator, xtarget, initiator; //content = <addmember><eventtime>1429186229164</eventtime><initiator>8:initiator</initiator><target>8:user</target></addmember> HXML xml = xmlParseString(ptrT(mir_a2t(content.c_str())), 0, _T("addmember")); if (xml == NULL) return; for (int i = 0; i < xmlGetChildCount(xml); i++) { HXML xmlNode = xmlGetNthChild(xml, L"target", i); if (xmlNode == NULL) break; xtarget = mir_t2a(xmlGetText(xmlNode)); CMStringA target = ParseUrl(xtarget, "8:"); AddChatContact(_A2T(chatname), target, target, L"User"); } xmlDestroyNode(xml); } else if (!mir_strcmpi(messageType.c_str(), "ThreadActivity/DeleteMember")) { ptrA xinitiator, xtarget; //content = <addmember><eventtime>1429186229164</eventtime><initiator>8:initiator</initiator><target>8:user</target></addmember> HXML xml = xmlParseString(ptrT(mir_a2t(content.c_str())), 0, _T("deletemember")); if (xml != NULL) { HXML xmlNode = xmlGetChildByPath(xml, _T("initiator"), 0); xinitiator = node != NULL ? mir_t2a(xmlGetText(xmlNode)) : NULL; xmlNode = xmlGetChildByPath(xml, _T("target"), 0); xtarget = xmlNode != NULL ? mir_t2a(xmlGetText(xmlNode)) : NULL; xmlDestroyNode(xml); } if (xtarget == NULL) return; CMStringA target = ParseUrl(xtarget, "8:"); CMStringA initiator = ParseUrl(xinitiator, "8:"); RemoveChatContact(_A2T(chatname), target, target, true, initiator); } else if (!mir_strcmpi(messageType.c_str(), "ThreadActivity/TopicUpdate")) { //content=<topicupdate><eventtime>1429532702130</eventtime><initiator>8:user</initiator><value>test topic</value></topicupdate> ptrA xinitiator, value; HXML xml = xmlParseString(ptrT(mir_a2t(content.c_str())), 0, _T("topicupdate")); if (xml != NULL) { HXML xmlNode = xmlGetChildByPath(xml, _T("initiator"), 0); xinitiator = xmlNode != NULL ? mir_t2a(xmlGetText(xmlNode)) : NULL; xmlNode = xmlGetChildByPath(xml, _T("value"), 0); value = xmlNode != NULL ? mir_t2a(xmlGetText(xmlNode)) : NULL; xmlDestroyNode(xml); } CMStringA initiator = ParseUrl(xinitiator, "8:"); RenameChat(chatname, value); ChangeChatTopic(chatname, value, initiator); } else if (!mir_strcmpi(messageType.c_str(), "ThreadActivity/RoleUpdate")) { //content=<roleupdate><eventtime>1429551258363</eventtime><initiator>8:user</initiator><target><id>8:user1</id><role>admin</role></target></roleupdate> ptrA xinitiator, xId, xRole; HXML xml = xmlParseString(ptrT(mir_a2t(content.c_str())), 0, _T("roleupdate")); if (xml != NULL) { HXML xmlNode = xmlGetChildByPath(xml, _T("initiator"), 0); xinitiator = xmlNode != NULL ? mir_t2a(xmlGetText(xmlNode)) : NULL; xmlNode = xmlGetChildByPath(xml, _T("target"), 0); if (xmlNode != NULL) { HXML xmlId = xmlGetChildByPath(xmlNode, _T("id"), 0); HXML xmlRole = xmlGetChildByPath(xmlNode, _T("role"), 0); xId = xmlId != NULL ? mir_t2a(xmlGetText(xmlId)) : NULL; xRole = xmlRole != NULL ? mir_t2a(xmlGetText(xmlRole)) : NULL; } xmlDestroyNode(xml); CMStringA initiator = ParseUrl(xinitiator, "8:"); CMStringA id = ParseUrl(xId, "8:"); GCDEST gcd = { m_szModuleName, _A2T(chatname), !mir_strcmpi(xRole, "Admin") ? GC_EVENT_ADDSTATUS : GC_EVENT_REMOVESTATUS }; GCEVENT gce = { sizeof(gce), &gcd }; ptrT tszId(mir_a2t(id)); ptrT tszRole(mir_a2t(xRole)); ptrT tszInitiator(mir_a2t(initiator)); gce.pDest = &gcd; gce.dwFlags = GCEF_ADDTOLOG; gce.ptszNick = tszId; gce.ptszUID = tszId; gce.ptszText = tszInitiator; gce.time = time(NULL); gce.bIsMe = IsMe(id); gce.ptszStatus = TranslateT("Admin"); CallServiceSync(MS_GC_EVENT, 0, (LPARAM)&gce); } } }
INT_PTR CSkypeProto::GetCallEventText(WPARAM, LPARAM lParam) { DBEVENTGETTEXT *pEvent = (DBEVENTGETTEXT *)lParam; INT_PTR nRetVal = 0; ptrA pszText; switch (pEvent->dbei->eventType) { case SKYPE_DB_EVENT_TYPE_CALL_INFO: { CMStringA text; HXML xml = xmlParseString(ptrT(mir_utf8decodeT((char*)pEvent->dbei->pBlob)), 0, _T("partlist")); if (xml != NULL) { ptrA type(mir_t2a(xmlGetAttrValue(xml, _T("type")))); bool bType = (!mir_strcmpi(type, "started")) ? 1 : 0; for (int i = 0; i < xmlGetChildCount(xml); i++) { HXML xmlPart = xmlGetNthChild(xml, _T("part"), i); if (xmlPart != NULL) { HXML xmlName = xmlGetChildByPath(xmlPart, _T("name"), 0); if (xmlName != NULL) { text.AppendFormat(Translate("%s %s this call.\n"), _T2A(xmlGetText(xmlName)), bType ? Translate("enters") : Translate("leaves")); xmlDestroyNode(xmlName); } xmlDestroyNode(xmlPart); } } xmlDestroyNode(xml); } pszText = mir_strdup(text.GetBuffer()); break; } case SKYPE_DB_EVENT_TYPE_FILETRANSFER_INFO: { CMStringA text; HXML xml = xmlParseString(ptrT(mir_utf8decodeT((char*)pEvent->dbei->pBlob)), 0, _T("files")); if (xml != NULL) { for (int i = 0; i < xmlGetChildCount(xml); i++) { size_t fileSize = 0; HXML xmlNode = xmlGetNthChild(xml, _T("file"), i); if (xmlNode != NULL) { fileSize = _ttoi(ptrT((TCHAR*)xmlGetAttrValue(xmlNode, _T("size")))); ptrA fileName(mir_utf8encodeT(ptrT((TCHAR*)xmlGetText(xmlNode)))); if (fileName != NULL) { CMStringA msg(FORMAT, Translate("File transfer:\n\tFile name: %s\n\tSize: %d bytes"), fileName, fileSize); text.AppendFormat("%s\n", msg); } xmlDestroyNode(xmlNode); } } xmlDestroyNode(xml); } pszText = mir_strdup(text.GetBuffer()); break; } case SKYPE_DB_EVENT_TYPE_URIOBJ: { CMStringA text; HXML xml = xmlParseString(ptrT(mir_utf8decodeT((char*)pEvent->dbei->pBlob)), 0, _T("URIObject")); if (xml != NULL) { text.Append(_T2A(xmlGetText(xml))); xmlDestroyNode(xml); } pszText = mir_strdup(text.GetBuffer()); break; } case SKYPE_DB_EVENT_TYPE_INCOMING_CALL: { pszText = Translate("Incoming call."); break; } default: { pszText = mir_strdup((char*)pEvent->dbei->pBlob); } } if (pEvent->datatype == DBVT_TCHAR) { TCHAR *pwszText = _A2T(pszText); nRetVal = (INT_PTR)mir_tstrdup(pwszText); } else if (pEvent->datatype == DBVT_ASCIIZ) nRetVal = (INT_PTR)mir_strdup(pszText); return nRetVal; }