From 71cfe74d3618c15feab24032c7d4cd71d77129af Mon Sep 17 00:00:00 2001 From: dartraiden Date: Tue, 7 Apr 2020 22:57:27 +0300 Subject: MSN: moved to deprecated, banned, removed support from plugins, etc --- protocols/MSN/src/msn_commands.cpp | 1219 ------------------------------------ 1 file changed, 1219 deletions(-) delete mode 100644 protocols/MSN/src/msn_commands.cpp (limited to 'protocols/MSN/src/msn_commands.cpp') diff --git a/protocols/MSN/src/msn_commands.cpp b/protocols/MSN/src/msn_commands.cpp deleted file mode 100644 index 993534d646..0000000000 --- a/protocols/MSN/src/msn_commands.cpp +++ /dev/null @@ -1,1219 +0,0 @@ -/* -Plugin of Miranda IM for communicating with users of the MSN Messenger protocol. - -Copyright (c) 2012-2020 Miranda NG team -Copyright (c) 2006-2012 Boris Krasnovskiy. -Copyright (c) 2003-2005 George Hazan. -Copyright (c) 2002-2003 Richard Hughes (original version). - -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; either version 2 -of the License, or (at your option) any later version. - -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" -#include "msn_proto.h" - -void CMsnProto::MSN_SetMirVer(MCONTACT hContact, MsnPlace *place) -{ - static const char* MirVerStr[] = - { - "Messenger (Windows)", - "Web", - "Windows Phone", - "Xbox", - "Zune", - "Messenger (iPhone) ", - "Messenger (Mac)", - "Messenger (SMS)", - "Messenger (Modern)", - "Skype", - "Skype (Windows)", - "Skype (Windows 8)", - "Skype (Mac)", - "Skype (Linux)", - "Skype (Windows Phone)", - "Skype (iOS)", - "Skype (Android)", - "Skype" - }; - - char szVersion[64]; - - if (!place || !place->client) return; - mir_snprintf(szVersion, sizeof(szVersion), "%s (%s)", - MirVerStr[place->client >= sizeof(MirVerStr) / sizeof(MirVerStr[0]) ? 9 : place->client - 1], place->szClientVer); - setString(hContact, "MirVer", szVersion); - setByte(hContact, "StdMirVer", 1); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// MSN_ReceiveMessage - receives message or a file from the server - -void CMsnProto::MSN_ReceiveMessage(ThreadData* info, char* cmdString, char* params) -{ - union - { - char* tWords[6]; - struct { char *fromEmail, *fromNick, *strMsgBytes; } data; - struct { char *fromEmail, *fromNetId, *toEmail, *toNetId, *typeId, *strMsgBytes; } datau; - struct { char *typeId, *strMsgBytes; } datas; - }; - - if (sttDivideWords(params, _countof(tWords), tWords) < 2) { - debugLogA("Invalid %.3s command, ignoring", cmdString); - return; - } - - int msgBytes; - char *nick = nullptr, *email = nullptr; - wchar_t *mChatID = nullptr; - bool ubmMsg = strncmp(cmdString, "UBM", 3) == 0; - bool sdgMsg = strncmp(cmdString, "SDG", 3) == 0; - bool nfyMsg = strncmp(cmdString, "NFY", 3) == 0; - bool sentMsg = false; - - if (sdgMsg) { - msgBytes = atol(datas.strMsgBytes); - if (mir_strcmpi(datas.typeId, "MSGR")) - return; - } - else if (nfyMsg) { - msgBytes = atol(datas.strMsgBytes); - if (mir_strcmpi(datas.typeId, "MSGR\\HOTMAIL")) - return; - } - else { - if (ubmMsg) { - msgBytes = atol(datau.strMsgBytes); - nick = datau.fromEmail; - email = datau.fromEmail; - } - else { - msgBytes = atol(data.strMsgBytes); - nick = data.fromNick; - email = data.fromEmail; - mir_urlDecode(nick); - } - stripBBCode(nick); - stripColorCode(nick); - } - - char* msg = (char*)alloca(msgBytes + 1); - - HReadBuffer buf(info, 0); - BYTE* msgb = buf.surelyRead(msgBytes); - if (msgb == nullptr) return; - - memcpy(msg, msgb, msgBytes); - msg[msgBytes] = 0; - - debugLogA("Message:\n%s", msg); - - MimeHeaders tHeader; - char* msgBody = tHeader.readFromBuffer(msg); - - if (sdgMsg) { - if (tHeader["Ack-Id"]) { - CMStringA szBody; - szBody.AppendFormat("Ack-Id: %s\r\n", tHeader["Ack-Id"]); - if (msnRegistration) szBody.AppendFormat("Registration: %s\r\n", msnRegistration); - szBody.AppendFormat("\r\n"); - msnNsThread->sendPacket("ACK", "MSGR %d\r\n%s", szBody.GetLength(), szBody.c_str()); - } - msgBody = tHeader.readFromBuffer(msgBody); - if (!(email = NEWSTR_ALLOCA(tHeader["From"]))) return; - mChatID = mir_a2u(tHeader["To"]); - if (wcsncmp(mChatID, L"19:", 3)) mChatID[0] = 0; // NETID_THREAD - msgBody = tHeader.readFromBuffer(msgBody); - msgBody = tHeader.readFromBuffer(msgBody); - nick = NEWSTR_ALLOCA(tHeader["IM-Display-Name"]); - if (!mir_strcmp(tHeader["Message-Type"], "RichText")) { - msgBody = NEWSTR_ALLOCA(msgBody); - stripHTML(msgBody); - HtmlDecode(msgBody); - } - } - else if (nfyMsg) msgBody = tHeader.readFromBuffer(msgBody); - else mChatID = info->mChatID; - - const char* tMsgId = tHeader["Message-ID"]; - if (tMsgId) lastMsgId = _atoi64(tMsgId); - - // Chunked message - char* newbody = nullptr; - if (!sdgMsg && tMsgId) { - int idx; - const char* tChunks = tHeader["Chunks"]; - if (tChunks) - idx = addCachedMsg(tMsgId, msg, 0, msgBytes, atol(tChunks), true); - else - idx = addCachedMsg(tMsgId, msgBody, 0, mir_strlen(msgBody), 0, true); - - size_t newsize; - if (!getCachedMsg(idx, newbody, newsize)) return; - msgBody = tHeader.readFromBuffer(newbody); - } - - // message from the server (probably) - if (!ubmMsg && !sdgMsg && !nfyMsg && strchr(email, '@') == nullptr && _stricmp(email, "Hotmail")) - return; - - const char* tContentType = tHeader["Content-Type"]; - if (tContentType == nullptr) - return; - - if (nfyMsg) - msgBody = tHeader.readFromBuffer(msgBody); - - if (!_strnicmp(tContentType, "text/x-clientcaps", 17)) { - MimeHeaders tFileInfo; - tFileInfo.readFromBuffer(msgBody); - info->firstMsgRecv = true; - - MCONTACT hContact = MSN_HContactFromEmail(email); - const char* mirver = tFileInfo["Client-Name"]; - if (hContact != NULL && mirver != nullptr) { - setString(hContact, "MirVer", mirver); - delSetting(hContact, "StdMirVer"); - } - } - else if (!ubmMsg && !sdgMsg && !nfyMsg && !info->firstMsgRecv) { - info->firstMsgRecv = true; - MsnContact *cont = Lists_Get(email); - if (cont && cont->hContact != NULL && cont->places.getCount() > 0) - MSN_SetMirVer(cont->hContact, &cont->places[0]); - } - - if (!_strnicmp(tContentType, "text/plain", 10) || - (!_strnicmp(tContentType, "application/user+xml", 10) && tHeader["Message-Type"] && !strncmp(tHeader["Message-Type"], "RichText", 8))) { - MCONTACT hContact = strncmp(email, "19:", 3) ? MSN_HContactFromEmail(email, nick, true, true) : NULL; - - if (!_stricmp(tHeader["Message-Type"], "RichText/UriObject") || !_stricmp(tHeader["Message-Type"], "RichText/Media_GenericFile")) { - ezxml_t xmli = ezxml_parse_str(msgBody, strlen(msgBody)); - if (xmli) { - MSN_ProcessURIObject(hContact, xmli); - ezxml_free(xmli); - } - } - else if (!_stricmp(tHeader["Message-Type"], "RichText/Contacts")) { - ezxml_t xmli = ezxml_parse_str(msgBody, mir_strlen(msgBody)); - if (xmli) { - if (!mir_strcmp(xmli->name, "contacts")) { - ezxml_t c; - int cnt; - PROTOSEARCHRESULT **psr; - - for (c = ezxml_child(xmli, "c"), cnt = 0; c; c = c->next) cnt++; - if (psr = (PROTOSEARCHRESULT**)mir_calloc(sizeof(PROTOSEARCHRESULT*) * cnt)) { - cnt = 0; - for (c = ezxml_child(xmli, "c"); c; c = c->next) { - const char *t = ezxml_attr(c, "t"), *wlid; - if (t && (wlid = ezxml_attr(c, t))) { - switch (*t) { - case 's': - case 'p': - psr[cnt] = (PROTOSEARCHRESULT*)mir_calloc(sizeof(PROTOSEARCHRESULT)); - psr[cnt]->cbSize = sizeof(psr); - psr[cnt]->flags = PSR_UNICODE; - psr[cnt]->id.w = psr[cnt]->nick.w = psr[cnt]->email.w = mir_a2u(wlid); - cnt++; - } - } - } - if (cnt) { - PROTORECVEVENT pre = { 0 }; - pre.timestamp = (DWORD)time(0); - pre.szMessage = (char *)psr; - pre.lParam = cnt; - ProtoChainRecv(hContact, PSR_CONTACTS, 0, (LPARAM)&pre); - for (cnt = 0; cnt < pre.lParam; cnt++) { - mir_free(psr[cnt]->email.w); - mir_free(psr[cnt]); - } - } - mir_free(psr); - } - } - ezxml_free(xmli); - } - } - else if (!_stricmp(tHeader["Message-Type"], "Control/Typing")) - CallService(MS_PROTO_CONTACTISTYPING, hContact, 7); - else if (!_stricmp(tHeader["Message-Type"], "Control/ClearTyping")) - CallService(MS_PROTO_CONTACTISTYPING, hContact, 0); - else { - const char* p = tHeader["X-MMS-IM-Format"]; - bool isRtl = p != nullptr && strstr(p, "RL=1") != nullptr; - - /*if (info->mJoinedContactsWLID.getCount() > 1) - MSN_ChatStart(info); - else */ { - char *szNet, *szEmail; - parseWLID(NEWSTR_ALLOCA(email), &szNet, &szEmail, nullptr); - sentMsg = _stricmp(szEmail, GetMyUsername(atoi(szNet))) == 0; - if (sentMsg) - hContact = ubmMsg ? MSN_HContactFromEmail(datau.toEmail, nick) : info->getContactHandle(); - } - - const char* tP4Context = tHeader["P4-Context"]; - if (tP4Context) { - size_t newlen = mir_strlen(msgBody) + mir_strlen(tP4Context) + 4; - char* newMsgBody = (char*)mir_alloc(newlen); - mir_snprintf(newMsgBody, newlen, "[%s] %s", tP4Context, msgBody); - mir_free(newbody); - msgBody = newbody = newMsgBody; - } - - if (mChatID[0]) { - if (!_strnicmp(tHeader["Message-Type"], "ThreadActivity/", 15)) { - ezxml_t xmli = ezxml_parse_str(msgBody, mir_strlen(msgBody)); - if (xmli) { - MSN_GCProcessThreadActivity(xmli, mChatID); - ezxml_free(xmli); - } - } - else MSN_GCAddMessage(mChatID, hContact, email, time(0), sentMsg, msgBody); - } - else if (hContact) { - if (!sentMsg) { - CallService(MS_PROTO_CONTACTISTYPING, WPARAM(hContact), 0); - - PROTORECVEVENT pre = { 0 }; - pre.szMessage = (char*)msgBody; - pre.flags = (isRtl ? PREF_RTL : 0); - pre.timestamp = (DWORD)time(0); - pre.lParam = 0; - ProtoChainRecvMsg(hContact, &pre); - } - else { - bool haveWnd = MSN_MsgWndExist(hContact); - - DBEVENTINFO dbei = {}; - dbei.eventType = EVENTTYPE_MESSAGE; - dbei.flags = DBEF_SENT | DBEF_UTF | (haveWnd ? 0 : DBEF_READ) | (isRtl ? DBEF_RTL : 0); - dbei.szModule = m_szModuleName; - dbei.timestamp = time(0); - dbei.cbBlob = (unsigned)mir_strlen(msgBody) + 1; - dbei.pBlob = (PBYTE)msgBody; - db_event_add(hContact, &dbei); - } - } - } - } - else if (!_strnicmp(tContentType, "text/x-msmsgsprofile", 20)) { - replaceStr(msnExternalIP, tHeader["ClientIP"]); - abchMigrated = atol(tHeader["ABCHMigrated"]); - langpref = atol(tHeader["lang_preference"]); - emailEnabled = atol(tHeader["EmailEnabled"]) != 0; - - if (!MSN_RefreshContactList()) { - ProtoBroadcastAck(NULL, ACKTYPE_LOGIN, ACKRESULT_FAILED, nullptr, LOGINERR_NOSERVER); - info->sendTerminate(); - } - else { - MSN_SetServerStatus(m_iDesiredStatus); - MSN_EnableMenuItems(true); - } - } - else if (!_strnicmp(tContentType, "text/x-msmsgscontrol", 20) || - (sdgMsg && !_strnicmp(tContentType, "Application/Message", 19))) { - const char* tTypingUser = sdgMsg ? email : tHeader["TypingUser"]; - - if (tTypingUser != nullptr && info->mChatID[0] == 0 && _stricmp(email, MyOptions.szEmail)) { - MCONTACT hContact = MSN_HContactFromEmail(tTypingUser, tTypingUser); - CallService(MS_PROTO_CONTACTISTYPING, hContact, - sdgMsg && !_stricmp(tHeader["Message-Type"], "Control/ClearTyping") ? 0 : 7); - } - } - else if (!_strnicmp(tContentType, "text/x-msnmsgr-datacast", 23)) { - //if (info->mJoinedContactsWLID.getCount()) { - MCONTACT tContact; - - if (mChatID[0]) { - GC_INFO gci = { 0 }; - gci.Flags = GCF_HCONTACT; - gci.pszModule = m_szModuleName; - gci.pszID = mChatID; - Chat_GetInfo(&gci); - tContact = gci.hContact; - } - else tContact = MSN_HContactFromEmail(email, nick, true, true); - if (!mir_strcmp(tHeader["Message-Type"], "Nudge")) - NotifyEventHooks(hMSNNudge, (WPARAM)tContact, 0); - /* Other msg types: - * Wink - * Voice - * Data - */ - } - else if (!_strnicmp(tContentType, "text/x-msmsgsemailnotification", 30)) - sttNotificationMessage(msgBody, false); - else if (!_strnicmp(tContentType, "text/x-msmsgsinitialemailnotification", 37)) - sttNotificationMessage(msgBody, true); - else if (!_strnicmp(tContentType, "text/x-msmsgsactivemailnotification", 35)) - sttNotificationMessage(msgBody, false); - else if (!_strnicmp(tContentType, "text/x-msmsgsinitialmdatanotification", 37)) - sttNotificationMessage(msgBody, true); - else if (!_strnicmp(tContentType, "text/x-msmsgsoimnotification", 28)) - sttNotificationMessage(msgBody, false); - - mir_free(mChatID); - mir_free(newbody); -} - -void CMsnProto::MSN_ProcessURIObject(MCONTACT hContact, ezxml_t xmli) -{ - const char *pszSkypeToken; - - if ((pszSkypeToken = authSkypeToken.Token()) && xmli) { - /* FIXME: As soon as core has functions to POST images in a conversation AND gives the possibility to supply a - * callback for fetching that image, this may be possible, but currently due to required Auth-Header, this - * is not possible and we just send an incoming file transfer - const char *thumb = ezxml_attr(xmli, "url_thumbnail"); - if (thumb && ServiceExists("IEVIEW/NewWindow")) { - // Supply callback to detch thumb with auth-header and embed [img] BB-code? - } - */ - char *uri = (char*)ezxml_attr(xmli, "uri"); - if (uri) { - // First get HTTP header of file to get content length - unsigned __int64 fileSize = 0; - NETLIBHTTPHEADER nlbhHeaders[2] = {}; - nlbhHeaders[0].szName = "User-Agent"; nlbhHeaders[0].szValue = (LPSTR)MSN_USER_AGENT; - nlbhHeaders[1].szName = "Authorization"; nlbhHeaders[1].szValue = (char*)pszSkypeToken; - - NETLIBHTTPREQUEST nlhr = {}; - nlhr.cbSize = sizeof(nlhr); - nlhr.requestType = REQUEST_GET; - nlhr.flags = NLHRF_PERSISTENT; - nlhr.szUrl = uri; - nlhr.headers = (NETLIBHTTPHEADER*)&nlbhHeaders; - nlhr.headersCount = _countof(nlbhHeaders); - nlhr.nlc = hHttpsConnection; - - mHttpsTS = clock(); - NLHR_PTR nlhrReply(Netlib_HttpTransaction(m_hNetlibUser, &nlhr)); - mHttpsTS = clock(); - if (nlhrReply) { - hHttpsConnection = nlhrReply->nlc; - if (nlhrReply->resultCode == 200) { - char *pLength, *pEnd; - - if ((pLength = strstr(nlhrReply->pData, "\"contents\":")) && - (pLength = strstr(pLength, "\"length\":")) && (pEnd = strchr(pLength + 9, ','))) { - pLength += 9; - *pEnd = 0; - fileSize = _atoi64(pLength); - } - } - } - else hHttpsConnection = nullptr; - - if (fileSize) { - filetransfer* ft = new filetransfer(this); - const char *pszFile = "", *pszType; - ezxml_t originalName, desc; - - ft->std.hContact = hContact; - ft->tType = SERVER_HTTP; - mir_free(ft->std.szCurrentFile.w); - if (!((originalName = ezxml_child(xmli, "OriginalName")) && (pszFile = (char*)ezxml_attr(originalName, "v")))) - if ((originalName = ezxml_child(xmli, "meta"))) - pszFile = ezxml_attr(originalName, "originalName"); - - if (!pszFile || !*pszFile) { - if ((originalName = ezxml_child(xmli, "meta")) && (pszFile = (char*)ezxml_attr(originalName, "type"))) - if (!mir_strcmp(pszFile, "photo")) - pszFile = "IMG00001.JPG"; - - if (!pszFile || !*pszFile) - pszFile = "file"; - } - - const char *p; - if ((p = strrchr(pszFile, '\\')) || (p = strrchr(pszFile, '/'))) - pszFile = p + 1; - - ft->std.szCurrentFile.w = mir_utf8decodeW(pszFile); - ft->std.totalBytes = ft->std.currentFileSize = fileSize; - ft->std.totalFiles = 1; - ft->szInvcookie = (char*)mir_calloc(strlen(uri) + 16); - if ((pszType = (char*)ezxml_attr(xmli, "type")) && !mir_strcmp(pszType, "File.1")) - sprintf(ft->szInvcookie, "%s/content/original", uri); - else - sprintf(ft->szInvcookie, "%s/content/imgpsh", uri); - - char tComment[40]; - mir_snprintf(tComment, TranslateU("%I64u bytes"), ft->std.currentFileSize); - - PROTORECVFILE pre = { 0 }; - pre.fileCount = 1; - pre.timestamp = time(0); - pre.descr.a = (desc = ezxml_child(xmli, "Description")) ? desc->txt : tComment; - pre.files.a = &pszFile; - pre.lParam = (LPARAM)ft; - ProtoChainRecvFile(ft->std.hContact, &pre); - } - else uri = nullptr; - } - - if (uri == nullptr) { - // Fallback: Just filter out the link and post it as a message - CallService(MS_PROTO_CONTACTISTYPING, WPARAM(hContact), 0); - - PROTORECVEVENT pre = { 0 }; - CMStringA msgtxt((char*)ezxml_txt(xmli)); - ezxml_t urllnk; - if (urllnk = ezxml_child(xmli, "a")) msgtxt.AppendFormat(" %s", ezxml_txt(urllnk)); - pre.szMessage = (char*)(const char*)msgtxt; - pre.timestamp = (DWORD)time(0); - ProtoChainRecvMsg(hContact, &pre); - } - } -} - -///////////////////////////////////////////////////////////////////////////////////////// -// Process Yahoo Find - -void CMsnProto::MSN_ProcessYFind(char* buf, size_t len) -{ - if (buf == nullptr) return; - ezxml_t xmli = ezxml_parse_str(buf, len); - - ezxml_t dom = ezxml_child(xmli, "d"); - const char* szDom = ezxml_attr(dom, "n"); - - ezxml_t cont = ezxml_child(dom, "c"); - const char* szCont = ezxml_attr(cont, "n"); - - char szEmail[128]; - mir_snprintf(szEmail, "%s@%s", szCont, szDom); - - const char *szNetId = ezxml_attr(cont, "t"); - if (msnSearchId != nullptr) { - if (szNetId != nullptr) { - ptrW szEmailT(mir_utf8decodeW(szEmail)); - - PROTOSEARCHRESULT psr = { 0 }; - psr.cbSize = sizeof(psr); - psr.flags = PSR_UNICODE; - psr.id.w = szEmailT; - psr.nick.w = szEmailT; - psr.email.w = szEmailT; - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_DATA, msnSearchId, (LPARAM)&psr); - } - ProtoBroadcastAck(NULL, ACKTYPE_SEARCH, ACKRESULT_SUCCESS, msnSearchId); - - msnSearchId = nullptr; - } - else { - if (szNetId != nullptr) { - int netId = atol(szNetId); - MCONTACT hContact = MSN_HContactFromEmail(szEmail, szEmail, true, false); - if (MSN_AddUser(hContact, szEmail, netId, LIST_FL)) { - MSN_AddUser(hContact, szEmail, netId, LIST_PL + LIST_REMOVE); - MSN_AddUser(hContact, szEmail, netId, LIST_BL + LIST_REMOVE); - MSN_AddUser(hContact, szEmail, netId, LIST_AL); - Contact_Hide(hContact, false); - } - MSN_SetContactDb(hContact, szEmail); - } - } - - ezxml_free(xmli); -} - -///////////////////////////////////////////////////////////////////////////////////////// -// MSN_HandleCommands - process commands from the server - -void CMsnProto::MSN_ProcessNLN(const char *userStatus, const char *wlid, char *userNick, const char *objid, char *cmdstring) -{ - if (userNick) { - mir_urlDecode(userNick); - stripBBCode(userNick); - stripColorCode(userNick); - } - - bool isMe = false; - char* szEmail, *szNet, *szInst; - parseWLID(NEWSTR_ALLOCA(wlid), &szNet, &szEmail, &szInst); - if (!mir_strcmpi(szEmail, GetMyUsername(atoi(szNet)))) { - if (!*userStatus) return; - isMe = true; - int newStatus = MSNStatusToMiranda(userStatus); - if (newStatus != m_iStatus && newStatus != ID_STATUS_IDLE) { - int oldMode = m_iStatus; - m_iDesiredStatus = m_iStatus = newStatus; - ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldMode, m_iStatus); - } - } - - WORD lastStatus = ID_STATUS_OFFLINE; - - MsnContact *cont = Lists_Get(szEmail); - - MCONTACT hContact = NULL; - if (!cont && !isMe) { - hContact = MSN_HContactFromEmail(wlid, userNick, true, true); - cont = Lists_Get(szEmail); - } - if (cont) hContact = cont->hContact; - - if (hContact != NULL) { - if (userNick) setStringUtf(hContact, "Nick", userNick); - lastStatus = getWord(hContact, "Status", ID_STATUS_OFFLINE); - if (lastStatus == ID_STATUS_OFFLINE || lastStatus == ID_STATUS_INVISIBLE) - db_unset(hContact, "CList", "StatusMsg"); - - int newStatus = MSNStatusToMiranda(userStatus); - setWord(hContact, "Status", newStatus != ID_STATUS_IDLE ? newStatus : ID_STATUS_AWAY); - setDword(hContact, "IdleTS", newStatus != ID_STATUS_IDLE ? 0 : time(0)); - } - - if (cont) { - if (objid) { - char* end = nullptr; - cont->cap1 = strtoul(objid, &end, 10); - cont->cap2 = end && *end == ':' ? strtoul(end + 1, nullptr, 10) : 0; - } - - if (szInst) MSN_SetMirVer(hContact, cont->places.find((MsnPlace*)&szInst)); - - char *pszUrl, *pszAvatarHash; - if (cmdstring && *cmdstring && mir_strcmp(cmdstring, "0") && - (pszAvatarHash = MSN_GetAvatarHash(cmdstring, &pszUrl))) { - setString(hContact, "PictContext", cmdstring); - setString(hContact, "AvatarHash", pszAvatarHash); - if (pszUrl) - setString(hContact, "AvatarUrl", pszUrl); - else - delSetting(hContact, "AvatarUrl"); - - if (hContact != NULL) { - char szSavedHash[64] = ""; - if (!db_get_static(hContact, m_szModuleName, "AvatarSavedHash", szSavedHash, sizeof(szSavedHash))) { - if (mir_strcmpi(szSavedHash, pszAvatarHash)) - pushAvatarRequest(hContact, pszUrl); - else { - char szSavedContext[64]; - int result = db_get_static(hContact, m_szModuleName, "PictSavedContext", szSavedContext, sizeof(szSavedContext)); - if (result || mir_strcmp(szSavedContext, cmdstring)) - pushAvatarRequest(hContact, pszUrl); - } - } - } - mir_free(pszAvatarHash); - mir_free(pszUrl); - } - else { - delSetting(hContact, "AvatarHash"); - delSetting(hContact, "AvatarSavedHash"); - delSetting(hContact, "AvatarUrl"); - delSetting(hContact, "PictContext"); - delSetting(hContact, "PictSavedContext"); - - ProtoBroadcastAck(hContact, ACKTYPE_AVATAR, ACKRESULT_STATUS, nullptr); - } - } - else if (lastStatus == ID_STATUS_OFFLINE) - delSetting(hContact, "MirVer"); -} - -void CMsnProto::MSN_ProcessStatusMessage(ezxml_t xmli, const char* wlid) -{ - MCONTACT hContact = MSN_HContactFromEmail(wlid); - if (hContact == NULL) return; - - char* szEmail, *szNetId, *szInst; - parseWLID(NEWSTR_ALLOCA(wlid), &szNetId, &szEmail, &szInst); - - bool bHasPSM = false; - char* szStatMsg = nullptr; - - for (ezxml_t s = ezxml_child(xmli, "s"); s; s = s->next) { - const char *n = ezxml_attr(s, "n"); - if (!mir_strcmp(n, "SKP")) { - szStatMsg = ezxml_txt(ezxml_child(s, "Mood")); - if (*szStatMsg) db_set_utf(hContact, "CList", "StatusMsg", szStatMsg); - else if (!bHasPSM) db_unset(hContact, "CList", "StatusMsg"); - } - else if (!mir_strcmp(n, "PE")) { - szStatMsg = ezxml_txt(ezxml_child(s, "PSM")); - if (*szStatMsg) { - stripBBCode((char*)szStatMsg); - stripColorCode((char*)szStatMsg); - db_set_utf(hContact, "CList", "StatusMsg", szStatMsg); - bHasPSM = true; - } - else db_unset(hContact, "CList", "StatusMsg"); - } - } - - // Add endpoints - for (ezxml_t endp = ezxml_child(xmli, "sep"); endp; endp = ezxml_next(endp)) { - const char *n = ezxml_attr(endp, "n"); - if (!mir_strcmp(n, "IM")) { - const char *id = ezxml_attr(endp, "epid"); - const char *caps = ezxml_txt(ezxml_child(endp, "Capabilities")); - char* end = nullptr; - unsigned cap1 = caps ? strtoul(caps, &end, 10) : 0; - unsigned cap2 = end && *end == ':' ? strtoul(end + 1, nullptr, 10) : 0; - - Lists_AddPlace(szEmail, id, cap1, cap2); - } - else if (!mir_strcmp(n, "PE")) { - MsnPlace *place = Lists_GetPlace(szEmail, ezxml_attr(endp, "epid")); - if (place) { - place->client = atoi(ezxml_txt(ezxml_child(endp, "TYP"))); - mir_strncpy(place->szClientVer, ezxml_txt(ezxml_child(endp, "VER")), sizeof(place->szClientVer)); - } - } - } - - if (szInst) - MSN_SetMirVer(hContact, Lists_GetPlace(szEmail, szInst)); - else { - MsnContact *cont = Lists_Get(hContact); - if (cont->places.getCount() > 0) - MSN_SetMirVer(hContact, &cont->places[0]); - } - ProtoBroadcastAck(hContact, ACKTYPE_AWAYMSG, ACKRESULT_SUCCESS, nullptr, ptrW(mir_utf8decodeW(szStatMsg))); -} - -void CMsnProto::MSN_ProcessNotificationMessage(char* buf, size_t len) -{ - if (buf == nullptr) return; - ezxml_t xmlnot = ezxml_parse_str(buf, len); - - if (mir_strcmp(ezxml_attr(xmlnot, "siteid"), "0") == 0) { - ezxml_free(xmlnot); - return; - } - - ezxml_t xmlmsg = ezxml_child(xmlnot, "MSG"); - ezxml_t xmlact = ezxml_child(xmlmsg, "ACTION"); - ezxml_t xmlbdy = ezxml_child(xmlmsg, "BODY"); - ezxml_t xmltxt = ezxml_child(xmlbdy, "TEXT"); - - if (xmltxt != nullptr) { - char fullurl[1024]; - size_t sz = 0; - - const char* acturl = ezxml_attr(xmlact, "url"); - if (acturl == nullptr || strstr(acturl, "://") == nullptr) - sz += mir_snprintf((fullurl + sz), (_countof(fullurl) - sz), "%s", ezxml_attr(xmlnot, "siteurl")); - - sz += mir_snprintf((fullurl + sz), (_countof(fullurl) - sz), "%s", acturl); - if (sz != 0 && fullurl[sz - 1] != '?') - sz += mir_snprintf((fullurl + sz), (_countof(fullurl) - sz), "?"); - - mir_snprintf((fullurl + sz), (_countof(fullurl) - sz), "notification_id=%s&message_id=%s", - ezxml_attr(xmlnot, "id"), ezxml_attr(xmlmsg, "id")); - - Skin_PlaySound(alertsoundname); - - wchar_t* alrt = mir_utf8decodeW(ezxml_txt(xmltxt)); - MSN_ShowPopup(TranslateT("MSN Alert"), alrt, MSN_ALERT_POPUP | MSN_ALLOW_MSGBOX, fullurl); - mir_free(alrt); - } - else if (xmlbdy) { - const char *txt = ezxml_txt(xmlbdy); - if (strstr(txt, "ABCHInternal")) { - MSN_SharingFindMembership(true); - MSN_ABFind("ABFindContactsPaged", nullptr, true); - MSN_StoreGetProfile(); - } - } - ezxml_free(xmlnot); -} - -int CMsnProto::MSN_HandleCommands(ThreadData* info, char* cmdString) -{ - char* params = ""; - int trid = -1; - - if (cmdString[3]) { - if (isdigit((BYTE)cmdString[4])) { - trid = strtol(cmdString + 4, ¶ms, 10); - switch (*params) { - case ' ': case '\0': case '\t': case '\n': - while (*params == ' ' || *params == '\t') - params++; - break; - - default: - params = cmdString + 4; - } - } - else params = cmdString + 4; - } - - switch ((*(PDWORD)cmdString & 0x00FFFFFF) | 0x20000000) { - - case ' SBS': - break; - - case ' HTA': //********* ATH: MSNP21+ Authentication - { - union - { - char* tWords[2]; - struct { char *typeId, *strMsgBytes; } data; - }; - - if (sttDivideWords(params, _countof(tWords), tWords) < 2) { -LBL_InvalidCommand: - debugLogA("Invalid %.3s command, ignoring", cmdString); - break; - } - - HReadBuffer buf(info, 0); - buf.surelyRead(atol(data.strMsgBytes)); - - if (!bIgnoreATH) { - if (!bSentBND) { - info->sendPacketPayload("BND", "CON\\MSGR", - "%d%s%s%s" - "%.*s\r\n", - msnP24Ver, (msnP24Ver > 1 ? "1" : ""), - msnStoreAppId, msnProductVer, - mir_strlen(MyOptions.szMachineGuid) - 2, MyOptions.szMachineGuid + 1); - bSentBND = true; - } - else { - msnLoggedIn = true; - isConnectSuccess = true; - emailEnabled = MyOptions.netId == NETID_MSN; // Let's assume it? - MSN_SetServerStatus(m_iDesiredStatus); - MSN_EnableMenuItems(true); - // Fork refreshing and populating contact list to the background - ForkThread(&CMsnProto::msn_loginThread, nullptr); - } - } - else bIgnoreATH = false; - } - break; - - case ' DNB': //********* BND: MSNP21+ bind request answer? - { - union - { - char* tWords[2]; - struct { char *typeId, *strMsgBytes; } data; - }; - - if (sttDivideWords(params, _countof(tWords), tWords) < 2) - goto LBL_InvalidCommand; - - MimeHeaders tHeader; - HReadBuffer buf(info, 0); - BYTE *msgb = buf.surelyRead(atol(data.strMsgBytes)); - if (!msgb) break; - char* msgBody = tHeader.readFromBuffer((char*)msgb); - - replaceStr(msnRegistration, tHeader["Set-Registration"]); - if (!mir_strcmp(data.typeId, "CON")) { - ezxml_t xmlbnd = ezxml_parse_str(msgBody, mir_strlen(msgBody)); - ezxml_t xmlbdy = ezxml_child(xmlbnd, "nonce"); - if (xmlbdy) { - char dgst[64]; - MSN_MakeDigest(xmlbdy->txt, dgst); - info->sendPacketPayload("PUT", "MSGR\\CHALLENGE", - "%s%s\r\n", - msnProductID, dgst); - } - ezxml_free(xmlbnd); - } - } - break; - - case ' TNC': //********* CNT: Connect, MSNP21+ Authentication - { - union - { - char* tWords[2]; - struct { char *typeId, *strMsgBytes; } data; - }; - - if (sttDivideWords(params, _countof(tWords), tWords) < 2) - goto LBL_InvalidCommand; - - HReadBuffer buf(info, 0); - char* msgBody = (char*)buf.surelyRead(atol(data.strMsgBytes)); - if (mir_strcmp(data.typeId, "CON")) break; - - if (MyOptions.netId != NETID_SKYPE) { - /* MSN account login */ - - if (MSN_AuthOAuth() < 1) { - m_iDesiredStatus = ID_STATUS_OFFLINE; - return 1; - } - - } - else { - /* Skype username/pass login */ - if (!msgBody) break; - ezxml_t xmlcnt = ezxml_parse_str(msgBody, mir_strlen(msgBody)); - ezxml_t xmlnonce = ezxml_child(xmlcnt, "nonce"); - if (xmlnonce) { - char szUIC[1024] = { 0 }; - - MSN_SkypeAuth(xmlnonce->txt, szUIC); - replaceStr(authUIC, szUIC); - } - ezxml_free(xmlcnt); - } - MSN_SendATH(info); - - bSentBND = false; - if (!hKeepAliveThreadEvt) - ForkThread(&CMsnProto::msn_keepAliveThread, nullptr); - } - break; - - case ' TEG': //********* GET: MSNP21+ GET reply - { - union - { - char* tWords[2]; - struct { char *typeId, *strMsgBytes; } data; - }; - - if (sttDivideWords(params, _countof(tWords), tWords) < 2) - goto LBL_InvalidCommand; - - MimeHeaders tHeader; - HReadBuffer buf(info, 0); - BYTE *msgb = buf.surelyRead(atol(data.strMsgBytes)); - if (!msgb) break; - char* msgBody = tHeader.readFromBuffer((char*)msgb); - ezxml_t xmli; - - if (tHeader["Set-Registration"]) replaceStr(msnRegistration, tHeader["Set-Registration"]); - if (xmli = ezxml_parse_str(msgBody, mir_strlen(msgBody))) { - if (!mir_strcmp(xmli->name, "recentconversations-response")) { - for (ezxml_t conv = ezxml_get(xmli, "conversations", 0, "conversation", -1); conv != nullptr; conv = ezxml_next(conv)) { - ezxml_t id; - MCONTACT hContact; - MEVENT hDbEvent; - DWORD ts = 1; - - if (ezxml_get(conv, "messages", 0, "message", -1) && (id = ezxml_child(conv, "id"))) { - if (strncmp(id->txt, "19:", 3) == 0) { - /* This is a thread (Groupchat) - * Find out about its current state on the server */ - hContact = MSN_HContactFromChatID(id->txt); - msnNsThread->sendPacketPayload("GET", "MSGR\\THREADS", - "%s", id->txt); - } - else hContact = MSN_HContactFromEmail(id->txt, nullptr, false, false); - - if (hContact) { - // There are messages to be fetched - if (hDbEvent = db_event_last(hContact)) { - DBEVENTINFO dbei = {}; - db_event_get(hDbEvent, &dbei); - ts = dbei.timestamp; - } - db_set_dw(hContact, m_szModuleName, "syncTS", ts); - } - msnNsThread->sendPacketPayload("GET", "MSGR\\MESSAGESBYCONVERSATION", - "%s%llu100", - id->txt, ((unsigned __int64)ts) * 1000); - } - } - } - else if (!mir_strcmp(xmli->name, "messagesbyconversation-response")) { - ezxml_t id; - MCONTACT hContact; - - if ((id = ezxml_child(xmli, "id"))) { - bool bIsChat = strncmp(id->txt, "19:", 3) == 0; - bool bHasMore = mir_strcmpi(ezxml_txt(ezxml_child(xmli, "hasmore")), "true") == 0; - ezxml_t syncstate; - hContact = MSN_HContactFromEmail(id->txt, nullptr, false, false); - if (!bHasMore && hContact) db_unset(hContact, m_szModuleName, "syncTS"); - - /* We have to traverse the list in reverse order as newest events are on top (which is the opposite direction of Groupchat) */ - LIST msgs(10, PtrKeySortT); - for (ezxml_t msg = ezxml_get(xmli, "messages", 0, "message", -1); msg != nullptr; msg = ezxml_next(msg)) msgs.insert(msg, 0); - for (auto &msg : msgs) { - ezxml_t arrtime = ezxml_child(msg, "originalarrivaltime"), from = ezxml_child(msg, "from"), - msgtype = ezxml_child(msg, "messagetype"), content = ezxml_child(msg, "content"); - time_t ts; - char *netId, *email, *message; - bool sentMsg; - - if (!arrtime || !from || !content) continue; - ts = IsoToUnixTime(arrtime->txt); - parseWLID(NEWSTR_ALLOCA(from->txt), &netId, &email, nullptr); - message = content->txt; - sentMsg = mir_strcmpi(email, GetMyUsername(atoi(netId))) == 0; - if (msgtype) { - if (!mir_strcmp(msgtype->txt, "RichText")) { - message = NEWSTR_ALLOCA(message); - stripHTML(message); - HtmlDecode(message); - } - else if (!strncmp(msgtype->txt, "ThreadActivity/", 15)) { - if (ezxml_t xmlact = ezxml_parse_str(content->txt, mir_strlen(content->txt))) { - MSN_GCProcessThreadActivity(xmlact, _A2T(id->txt)); - ezxml_free(xmlact); - } - continue; - } - else if (!mir_strcmp(msgtype->txt, "RichText/UriObject") || !mir_strcmp(msgtype->txt, "RichText/Media_GenericFile")) { - if (ezxml_t xmlact = ezxml_parse_str(content->txt, mir_strlen(content->txt))) { - MSN_ProcessURIObject(hContact, xmlact); - ezxml_free(xmlact); - } - continue; - } - else if (mir_strcmp(msgtype->txt, "Text")) continue; /* TODO: Implement i.e. RichText/Files for announcement of file transfers */ - } - - if (bIsChat) { - hContact = MSN_HContactFromEmail(from->txt, nullptr, false, false); - if (hContact) - db_unset(hContact, m_szModuleName, "syncTS"); - MSN_GCAddMessage(_A2T(id->txt), hContact, email, ts, sentMsg, message); - } - else if (hContact) { - /* Protect against double sync (Miranda MSGs only have granularity in seconds) */ - MEVENT hDbEvent; - bool bDuplicate = false; - DBEVENTINFO dbei = {}; - DWORD cbBlob = (DWORD)mir_strlen(message); - dbei.cbBlob = cbBlob; - BYTE *pszMsgBuf = (BYTE*)mir_calloc(cbBlob); - if (pszMsgBuf) { - dbei.pBlob = pszMsgBuf; - for ((hDbEvent = db_event_last(hContact)); - !bDuplicate && hDbEvent; - hDbEvent = db_event_prev(hContact, hDbEvent)) { - if (db_event_get(hDbEvent, &dbei) || dbei.timestamp > ts + 1 || dbei.timestamp < ts) break; - if (!memcmp((char*)dbei.pBlob, message, cbBlob)) bDuplicate = true; - dbei.cbBlob = cbBlob; - } - mir_free(pszMsgBuf); - if (bDuplicate) continue; - } - - if (!sentMsg) { - PROTORECVEVENT pre = { 0 }; - pre.szMessage = (char*)message; - pre.timestamp = (DWORD)ts; - ProtoChainRecvMsg(hContact, &pre); - } - else { - memset(&dbei, 0, sizeof(dbei)); - dbei.eventType = EVENTTYPE_MESSAGE; - dbei.flags = DBEF_SENT | DBEF_UTF; - dbei.szModule = m_szModuleName; - dbei.timestamp = ts; - dbei.cbBlob = (unsigned)mir_strlen(message) + 1; - dbei.pBlob = (PBYTE)message; - db_event_add(hContact, &dbei); - } - } - } - /* In groupchat it wouldn't make much sense to sync more as older messages are coming now and that would jumble our log */ - if (!bIsChat && bHasMore && (syncstate = ezxml_child(xmli, "messagessyncstate"))) { - msnNsThread->sendPacketPayload("GET", "MSGR\\MESSAGESBYCONVERSATION", - "%s%llu%s100", - id->txt, ((unsigned __int64)db_get_dw(hContact, m_szModuleName, "syncTS", 1000)) * 1000, syncstate->txt); - } - msgs.destroy(); - } - } - else if (!mir_strcmp(xmli->name, "threads-response")) { - for (ezxml_t thread = ezxml_get(xmli, "threads", 0, "thread", -1); thread != nullptr; thread = ezxml_next(thread)) - MSN_ChatStart(thread); - } - ezxml_free(xmli); - } - - } - break; - - case ' YFN': //********* NFY: MSNP21+ Notifications - { - union - { - char* tWords[2]; - struct { char *typeId, *strMsgBytes; } data; - }; - - if (sttDivideWords(params, _countof(tWords), tWords) < 2) - goto LBL_InvalidCommand; - - HReadBuffer buf(info, 0); - char* msgBody = (char*)buf.surelyRead(atol(data.strMsgBytes)); - if (msgBody == nullptr) break; - if (!mir_strcmp(data.typeId, "MSGR\\HOTMAIL")) { - char szParam[128]; - mir_snprintf(szParam, sizeof(szParam), "%s %s", data.typeId, data.strMsgBytes); - MSN_ReceiveMessage(info, cmdString, szParam); - break; - } - else if (!mir_strcmp(data.typeId, "MSGR\\ABCH")) { - MimeHeaders tHeader; - msgBody = tHeader.readFromBuffer(msgBody); - MSN_ProcessNotificationMessage(msgBody, mir_strlen(msgBody)); - break; - } - - if (!mir_strcmp(data.typeId, "MSGR\\PUT") || !mir_strcmp(data.typeId, "MSGR\\DEL")) { - MimeHeaders tHeader; - - int i; - for (i = 0; i < 2; i++) msgBody = tHeader.readFromBuffer(msgBody); - char *pszTo = nullptr, *pszToNet; - if (tHeader["To"]) parseWLID(NEWSTR_ALLOCA(tHeader["To"]), &pszToNet, &pszTo, nullptr); - const char *pszFrom = tHeader["From"]; - for (i = 0; i < 2; i++) msgBody = tHeader.readFromBuffer(msgBody); - - if (pszFrom) { - ezxml_t xmli; - if (xmli = ezxml_parse_str(msgBody, mir_strlen(msgBody))) { - if (!mir_strcmp(xmli->name, "user")) { - ezxml_t xmlstatus = ezxml_get(xmli, "s", 0, "Status", -1); - /* FIXME: MSGR\DEL: Instance of user with given EPID disconnected, not - * sure if this implies that contact is offline now... */ - if (xmlstatus || !mir_strcmp(data.typeId, "MSGR\\DEL")) { - // These capabilities seem to be something different than in previous MSNP versions? - //ezxml_t xmlcaps = ezxml_get(xmli, "sep", 0, "Capabilities", -1); - ezxml_t usertile = ezxml_get(xmli, "s", 1, "UserTileLocation", -1); - MSN_ProcessNLN(ezxml_txt(xmlstatus), pszFrom, nullptr, nullptr, usertile ? usertile->txt : nullptr); - } - MSN_ProcessStatusMessage(xmli, pszFrom); - } - ezxml_free(xmli); - } - } - } - else if (!mir_strcmp(data.typeId, "MSGR\\THREAD")) { - MimeHeaders tHeader; - char *szBody = tHeader.readFromBuffer(info->mData); - ezxml_t xmli = ezxml_parse_str(szBody, mir_strlen(szBody)); - if (xmli) { - MSN_ChatStart(xmli); - ezxml_free(xmli); - } - } - } - break; - - case ' TUP': //******** MSNP21+: PUT notifications - case ' GNP': //******** MSNP21+: PNG reply - { - union - { - char* tWords[2]; - struct { char *typeId, *strMsgBytes; } data; - }; - - if (sttDivideWords(params, _countof(tWords), tWords) < 2) - goto LBL_InvalidCommand; - - MimeHeaders tHeader; - HReadBuffer buf(info, 0); - BYTE *msgb = buf.surelyRead(atol(data.strMsgBytes)); - if (!msgb) break; - char* msgBody = tHeader.readFromBuffer((char*)msgb); - - if (tHeader["Set-Registration"]) replaceStr(msnRegistration, tHeader["Set-Registration"]); - if (cmdString[1] == 'N') { // PNG - if (ezxml_t xmli = ezxml_parse_str(msgBody, mir_strlen(msgBody))) { - if (ezxml_t wait = ezxml_child(xmli, "wait")) { - msnPingTimeout = atoi(ezxml_txt(wait)); - if (msnPingTimeout && hKeepAliveThreadEvt != nullptr) - SetEvent(hKeepAliveThreadEvt); - } - ezxml_free(xmli); - } - } - else { // PUT - ezxml_t xmli; - if (*msgBody && (xmli = ezxml_parse_str(msgBody, mir_strlen(msgBody)))) { - if (!mir_strcmp(xmli->name, "presence-response")) { - ezxml_t user, from; - if ((user = ezxml_child(xmli, "user")) && (from = ezxml_child(xmli, "from"))) { - if (ezxml_t xmlstatus = ezxml_get(user, "s", 0, "Status", -1)) { - ezxml_t usertile = ezxml_get(user, "s", 1, "UserTileLocation", -1); - MSN_ProcessNLN(ezxml_txt(xmlstatus), from->txt, nullptr, nullptr, usertile ? usertile->txt : nullptr); - } - else { - int oldMode = m_iStatus; - m_iStatus = m_iDesiredStatus; - ProtoBroadcastAck(NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, (HANDLE)oldMode, m_iStatus); - } - MSN_ProcessStatusMessage(user, from->txt); - } - } - ezxml_free(xmli); - } - } - } - break; - - case ' GDS': // SDG: MSNP21+ Messaging - MSN_ReceiveMessage(info, cmdString, params); - break; - - case ' RFX': //******** XFR: sections 7.4 Referral, 8.1 Referral to Switchboard - { - union - { - char* tWords[2]; - struct { char *typeId, *strMsgBytes; } data; - }; - - if (sttDivideWords(params, _countof(tWords), tWords) < 2) - goto LBL_InvalidCommand; - - MimeHeaders tHeader; - HReadBuffer buf(info, 0); - BYTE *msgb = buf.surelyRead(atol(data.strMsgBytes)); - if (!msgb) break; - char* msgBody = tHeader.readFromBuffer((char*)msgb); - if (!mir_strcmp(data.typeId, "CON")) { - ezxml_t xmlxfr = ezxml_parse_str(msgBody, mir_strlen(msgBody)); - ezxml_t xmltgt = ezxml_child(xmlxfr, "target"); - if (xmltgt) { - ThreadData* newThread = new ThreadData; - mir_strcpy(newThread->mServer, xmltgt->txt); - mir_strcpy(newThread->mState, ezxml_txt(ezxml_child(xmlxfr, "state"))); - newThread->mType = SERVER_NOTIFICATION; - newThread->mTrid = info->mTrid; - newThread->mIsMainThread = true; - info->mIsMainThread = false; - - debugLogA("Switching to notification server '%s'...", xmltgt->txt); - newThread->startThread(&CMsnProto::MSNServerThread, this); - ezxml_free(xmlxfr); - return 1; //kill the old thread - } - ezxml_free(xmlxfr); - } - } - break; - - default: - debugLogA("Unrecognised message: %s", cmdString); - break; - } - - return 0; -} -- cgit v1.2.3