/* Jabber Protocol Plugin for Miranda IM Copyright (C) 2002-04 Santithorn Bunchua Copyright (C) 2005-12 George Hazan Copyright (C) 2007 Maxim Mluhov 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, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "jabber.h" #include #include #include #include #include "jabber_list.h" #include "jabber_iq.h" #include "jabber_caps.h" #include "m_file.h" #include "m_addcontact.h" #include "jabber_disco.h" #include "m_proto_listeningto.h" ///////////////////////////////////////////////////////////////////////////////////////// // OnContactDeleted - processes a contact deletion int CJabberProto::OnContactDeleted(WPARAM wParam, LPARAM) { if ( !m_bJabberOnline) // should never happen return 0; DBVARIANT dbv; if ( !JGetStringT((HANDLE)wParam, JGetByte((HANDLE) wParam, "ChatRoom", 0)?(char*)"ChatRoomID":(char*)"jid", &dbv)) { if (ListExist(LIST_ROSTER, dbv.ptszVal)) { if ( !_tcschr(dbv.ptszVal, _T('@'))) { TCHAR szStrippedJid[JABBER_MAX_JID_LEN]; JabberStripJid(m_ThreadInfo->fullJID, szStrippedJid, SIZEOF(szStrippedJid)); TCHAR *szDog = _tcschr(szStrippedJid, _T('@')); if (szDog && _tcsicmp(szDog + 1, dbv.ptszVal)) m_ThreadInfo->send( XmlNodeIq(_T("set"), SerialNext(), dbv.ptszVal) << XQUERY(_T(JABBER_FEAT_REGISTER)) << XCHILD(_T("remove"))); } // Remove from roster, server also handles the presence unsubscription process. m_ThreadInfo->send( XmlNodeIq(_T("set"), SerialNext()) << XQUERY(_T(JABBER_FEAT_IQ_ROSTER)) << XCHILD(_T("item")) << XATTR(_T("jid"), dbv.ptszVal) << XATTR(_T("subscription"), _T("remove"))); } db_free(&dbv); } return 0; } ///////////////////////////////////////////////////////////////////////////////////////// // JabberDbSettingChanged - process database changes static TCHAR* sttSettingToTchar(DBCONTACTWRITESETTING* cws) { switch(cws->value.type) { case DBVT_ASCIIZ: return mir_a2t(cws->value.pszVal); case DBVT_UTF8: return mir_utf8decodeT(cws->value.pszVal); case DBVT_WCHAR: return mir_u2t(cws->value.pwszVal); } return NULL; } void __cdecl CJabberProto::OnRenameGroup(DBCONTACTWRITESETTING* cws, HANDLE hContact) { DBVARIANT jid, dbv; if (JGetStringT(hContact, "jid", &jid)) return; JABBER_LIST_ITEM* item = ListGetItemPtr(LIST_ROSTER, jid.ptszVal); db_free(&jid); if (item == NULL) return; TCHAR* nick; if ( !DBGetContactSettingTString(hContact, "CList", "MyHandle", &dbv)) { nick = mir_tstrdup(dbv.ptszVal); db_free(&dbv); } else if ( !JGetStringT(hContact, "Nick", &dbv)) { nick = mir_tstrdup(dbv.ptszVal); db_free(&dbv); } else nick = JabberNickFromJID(item->jid); if (nick == NULL) return; if (cws->value.type == DBVT_DELETED) { if (item->group != NULL) { Log("Group set to nothing"); AddContactToRoster(item->jid, nick, NULL); } } else { TCHAR* p = sttSettingToTchar(cws); if (cws->value.pszVal != NULL && lstrcmp(p, item->group)) { Log("Group set to " TCHAR_STR_PARAM, p); if (p) AddContactToRoster(item->jid, nick, p); } mir_free(p); } mir_free(nick); } void __cdecl CJabberProto::OnRenameContact(DBCONTACTWRITESETTING* cws, HANDLE hContact) { DBVARIANT jid; if (JGetStringT(hContact, "jid", &jid)) return; JABBER_LIST_ITEM* item = ListGetItemPtr(LIST_ROSTER, jid.ptszVal); db_free(&jid); if (item == NULL) return; if (cws->value.type == DBVT_DELETED) { TCHAR* nick = (TCHAR*)CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, GCDNF_NOMYHANDLE | GCDNF_TCHAR); AddContactToRoster(item->jid, nick, item->group); mir_free(nick); return; } TCHAR* newNick = sttSettingToTchar(cws); if (newNick) { if (lstrcmp(item->nick, newNick)) { Log("Renaming contact " TCHAR_STR_PARAM ": " TCHAR_STR_PARAM " -> " TCHAR_STR_PARAM, item->jid, item->nick, newNick); AddContactToRoster(item->jid, newNick, item->group); } mir_free(newNick); } } void __cdecl CJabberProto::OnAddContactForever(DBCONTACTWRITESETTING* cws, HANDLE hContact) { if (cws->value.type != DBVT_DELETED && !(cws->value.type==DBVT_BYTE && cws->value.bVal==0)) return; DBVARIANT jid, dbv; if (JGetStringT(hContact, "jid", &jid)) return; TCHAR *nick; Log("Add " TCHAR_STR_PARAM " permanently to list", jid.pszVal); if ( !DBGetContactSettingTString(hContact, "CList", "MyHandle", &dbv)) { nick = mir_tstrdup(dbv.ptszVal); db_free(&dbv); } else if ( !JGetStringT(hContact, "Nick", &dbv)) { nick = mir_tstrdup(dbv.ptszVal); db_free(&dbv); } else nick = JabberNickFromJID(jid.ptszVal); if (nick == NULL) { db_free(&jid); return; } if ( !DBGetContactSettingTString(hContact, "CList", "Group", &dbv)) { AddContactToRoster(jid.ptszVal, nick, dbv.ptszVal); db_free(&dbv); } else AddContactToRoster(jid.ptszVal, nick, NULL); m_ThreadInfo->send(XmlNode(_T("presence")) << XATTR(_T("to"), jid.ptszVal) << XATTR(_T("type"), _T("subscribe"))); SendGetVcard(jid.ptszVal); mir_free(nick); db_unset(hContact, "CList", "Hidden"); db_free(&jid); } int __cdecl CJabberProto::OnDbSettingChanged(WPARAM wParam, LPARAM lParam) { HANDLE hContact = (HANDLE)wParam; if (hContact == NULL || !m_bJabberOnline) return 0; DBCONTACTWRITESETTING* cws = (DBCONTACTWRITESETTING*)lParam; if (strcmp(cws->szModule, "CList")) return 0; if ( !strcmp(cws->szSetting, "Group")) OnRenameGroup(cws, hContact); else if ( !strcmp(cws->szSetting, "MyHandle")) OnRenameContact(cws, hContact); else if ( !strcmp(cws->szSetting, "NotOnList")) OnAddContactForever(cws, hContact); return 0; } ///////////////////////////////////////////////////////////////////////////////////////// // OnIdleChanged - tracks idle start time for XEP-0012 support int CJabberProto::OnIdleChanged(WPARAM, LPARAM lParam) { // don't report idle time, if user disabled if (lParam & IDF_PRIVACY) { m_tmJabberIdleStartTime = 0; return 0; } if (lParam & IDF_ISIDLE) { MIRANDA_IDLE_INFO mii = { 0 }; mii.cbSize = sizeof(mii); CallService(MS_IDLE_GETIDLEINFO, 0, (LPARAM)&mii); m_tmJabberIdleStartTime = time(0) - mii.idleTime * 60; } else m_tmJabberIdleStartTime = 0; return 0; }