From 48540940b6c28bb4378abfeb500ec45a625b37b6 Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Tue, 15 May 2012 10:38:20 +0000 Subject: initial commit git-svn-id: http://svn.miranda-ng.org/main/trunk@2 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/JabberG/jabber_misc.cpp | 648 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 648 insertions(+) create mode 100644 protocols/JabberG/jabber_misc.cpp (limited to 'protocols/JabberG/jabber_misc.cpp') diff --git a/protocols/JabberG/jabber_misc.cpp b/protocols/JabberG/jabber_misc.cpp new file mode 100644 index 0000000000..dadbe21673 --- /dev/null +++ b/protocols/JabberG/jabber_misc.cpp @@ -0,0 +1,648 @@ +/* + +Jabber Protocol Plugin for Miranda IM +Copyright ( C ) 2002-04 Santithorn Bunchua +Copyright ( C ) 2005-11 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. + +Revision : $Revision: 13898 $ +Last change on : $Date: 2006-07-13 16:11:29 +0400 +Last change by : $Author: borkra $ + +*/ + +#include "jabber.h" +#include "jabber_list.h" +#include "jabber_caps.h" + +#include +#include "sdk/m_folders.h" + +/////////////////////////////////////////////////////////////////////////////// +// JabberAddContactToRoster() - adds a contact to the roster + +void CJabberProto::AddContactToRoster( const TCHAR* jid, const TCHAR* nick, const TCHAR* grpName ) +{ + XmlNodeIq iq( _T("set"), SerialNext()); + HXML query = iq << XQUERY( _T(JABBER_FEAT_IQ_ROSTER)) + << XCHILD( _T("item")) << XATTR( _T("jid"), jid ) << XATTR( _T("name"), nick ); + if ( grpName ) + query << XCHILD( _T("group"), grpName ); + m_ThreadInfo->send( iq ); +} + +/////////////////////////////////////////////////////////////////////////////// +// JabberChatDllError() - missing CHAT.DLL + +void JabberChatDllError() +{ + MessageBox( NULL, + TranslateT( "CHAT plugin is required for conferences. Install it before chatting" ), + TranslateT( "Jabber Error" ), MB_OK|MB_SETFOREGROUND ); +} + +/////////////////////////////////////////////////////////////////////////////// +// JabberCompareJids + +int JabberCompareJids( const TCHAR* jid1, const TCHAR* jid2 ) +{ + if ( !lstrcmpi( jid1, jid2 )) + return 0; + + // match only node@domain part + TCHAR szTempJid1[ JABBER_MAX_JID_LEN ], szTempJid2[ JABBER_MAX_JID_LEN ]; + return lstrcmpi( + JabberStripJid( jid1, szTempJid1, SIZEOF(szTempJid1) ), + JabberStripJid( jid2, szTempJid2, SIZEOF(szTempJid2)) ); +} + +/////////////////////////////////////////////////////////////////////////////// +// JabberContactListCreateGroup() + +static void JabberContactListCreateClistGroup( TCHAR* groupName ) +{ + char str[33]; + int i; + DBVARIANT dbv; + + for ( i=0;;i++ ) { + _itoa( i, str, 10 ); + if ( DBGetContactSettingTString( NULL, "CListGroups", str, &dbv )) + break; + TCHAR* name = dbv.ptszVal; + if ( name[0]!='\0' && !_tcscmp( name+1, groupName )) { + // Already exists, no need to create + JFreeVariant( &dbv ); + return; + } + JFreeVariant( &dbv ); + } + + // Create new group with id = i ( str is the text representation of i ) + TCHAR newName[128]; + newName[0] = 1 | GROUPF_EXPANDED; + _tcsncpy( newName+1, groupName, SIZEOF( newName )-1 ); + newName[ SIZEOF( newName )-1] = '\0'; + DBWriteContactSettingTString( NULL, "CListGroups", str, newName ); + JCallService( MS_CLUI_GROUPADDED, i+1, 0 ); +} + +void JabberContactListCreateGroup( TCHAR* groupName ) +{ + TCHAR name[128], *p; + + if ( groupName==NULL || groupName[0]=='\0' || groupName[0]=='\\' ) return; + + _tcsncpy( name, groupName, SIZEOF( name )); + name[ SIZEOF( name )-1] = '\0'; + for ( p=name; *p!='\0'; p++ ) { + if ( *p == '\\' ) { + *p = '\0'; + JabberContactListCreateClistGroup( name ); + *p = '\\'; + } + } + JabberContactListCreateClistGroup( name ); +} + +/////////////////////////////////////////////////////////////////////////////// +// JabberDBAddAuthRequest() + +void CJabberProto::DBAddAuthRequest( const TCHAR* jid, const TCHAR* nick ) +{ + HANDLE hContact = DBCreateContact( jid, NULL, TRUE, TRUE ); + JDeleteSetting( hContact, "Hidden" ); + //JSetStringT( hContact, "Nick", nick ); + + char* szJid = mir_utf8encodeT( jid ); + char* szNick = mir_utf8encodeT( nick ); + + //blob is: uin( DWORD ), hContact( HANDLE ), nick( ASCIIZ ), first( ASCIIZ ), last( ASCIIZ ), email( ASCIIZ ), reason( ASCIIZ ) + //blob is: 0( DWORD ), hContact( HANDLE ), nick( ASCIIZ ), ""( ASCIIZ ), ""( ASCIIZ ), email( ASCIIZ ), ""( ASCIIZ ) + DBEVENTINFO dbei = {0}; + dbei.cbSize = sizeof( DBEVENTINFO ); + dbei.szModule = m_szModuleName; + dbei.timestamp = ( DWORD )time( NULL ); + dbei.flags = DBEF_UTF; + dbei.eventType = EVENTTYPE_AUTHREQUEST; + dbei.cbBlob = (DWORD)(sizeof( DWORD )+ sizeof( HANDLE ) + strlen( szNick ) + strlen( szJid ) + 5); + PBYTE pCurBlob = dbei.pBlob = ( PBYTE ) mir_alloc( dbei.cbBlob ); + *(( PDWORD ) pCurBlob ) = 0; pCurBlob += sizeof( DWORD ); + *(( PHANDLE ) pCurBlob ) = hContact; pCurBlob += sizeof( HANDLE ); + strcpy(( char* )pCurBlob, szNick ); pCurBlob += strlen( szNick )+1; + *pCurBlob = '\0'; pCurBlob++; //firstName + *pCurBlob = '\0'; pCurBlob++; //lastName + strcpy(( char* )pCurBlob, szJid ); pCurBlob += strlen( szJid )+1; + *pCurBlob = '\0'; //reason + + JCallService( MS_DB_EVENT_ADD, ( WPARAM ) ( HANDLE ) NULL, ( LPARAM )&dbei ); + Log( "Setup DBAUTHREQUEST with nick='%s' jid='%s'", szNick, szJid ); + + mir_free( szJid ); + mir_free( szNick ); +} + +/////////////////////////////////////////////////////////////////////////////// +// JabberDBCreateContact() + +HANDLE CJabberProto::DBCreateContact( const TCHAR* jid, const TCHAR* nick, BOOL temporary, BOOL stripResource ) +{ + TCHAR* s, *p, *q; + size_t len; + char* szProto; + + if ( jid==NULL || jid[0]=='\0' ) + return NULL; + + s = mir_tstrdup( jid ); + q = NULL; + // strip resource if present + if (( p = _tcschr( s, '@' )) != NULL ) + if (( q = _tcschr( p, '/' )) != NULL ) + *q = '\0'; + + if ( !stripResource && q!=NULL ) // so that resource is not stripped + *q = '/'; + len = _tcslen( s ); + + // We can't use JabberHContactFromJID() here because of the stripResource option + HANDLE hContact = ( HANDLE ) JCallService( MS_DB_CONTACT_FINDFIRST, 0, 0 ); + while ( hContact != NULL ) { + szProto = ( char* )JCallService( MS_PROTO_GETCONTACTBASEPROTO, ( WPARAM ) hContact, 0 ); + if ( szProto!=NULL && !strcmp( m_szModuleName, szProto )) { + DBVARIANT dbv; + if ( !JGetStringT( hContact, "jid", &dbv )) { + p = dbv.ptszVal; + if ( p && _tcslen( p )>=len && ( p[len]=='\0'||p[len]=='/' ) && !_tcsnicmp( p, s, len )) { + JFreeVariant( &dbv ); + break; + } + JFreeVariant( &dbv ); + } } + hContact = ( HANDLE ) JCallService( MS_DB_CONTACT_FINDNEXT, ( WPARAM ) hContact, 0 ); + } + + if ( hContact == NULL ) { + hContact = ( HANDLE ) JCallService( MS_DB_CONTACT_ADD, 0, 0 ); + JCallService( MS_PROTO_ADDTOCONTACT, ( WPARAM ) hContact, ( LPARAM )m_szModuleName ); + JSetStringT( hContact, "jid", s ); + if ( nick != NULL && *nick != '\0' ) + JSetStringT( hContact, "Nick", nick ); + if ( temporary ) + DBWriteContactSettingByte( hContact, "CList", "NotOnList", 1 ); + else + SendGetVcard( s ); + Log( "Create Jabber contact jid=" TCHAR_STR_PARAM ", nick=" TCHAR_STR_PARAM, s, nick ); + DBCheckIsTransportedContact(s,hContact); + } + + mir_free( s ); + return hContact; +} + +BOOL CJabberProto::AddDbPresenceEvent(HANDLE hContact, BYTE btEventType) +{ + if ( !hContact ) + return FALSE; + + switch ( btEventType ) { + case JABBER_DB_EVENT_PRESENCE_SUBSCRIBE: + case JABBER_DB_EVENT_PRESENCE_SUBSCRIBED: + case JABBER_DB_EVENT_PRESENCE_UNSUBSCRIBE: + case JABBER_DB_EVENT_PRESENCE_UNSUBSCRIBED: + if ( !m_options.LogPresence ) + return FALSE; + break; + + case JABBER_DB_EVENT_PRESENCE_ERROR: + if ( !m_options.LogPresenceErrors ) + return FALSE; + break; + } + + DBEVENTINFO dbei; + dbei.cbSize = sizeof( dbei ); + dbei.pBlob = &btEventType; + dbei.cbBlob = sizeof( btEventType ); + dbei.eventType = JABBER_DB_EVENT_TYPE_PRESENCE; + dbei.flags = DBEF_READ; + dbei.timestamp = time( NULL ); + dbei.szModule = m_szModuleName; + CallService( MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei ); + + return TRUE; +} + +/////////////////////////////////////////////////////////////////////////////// +// JabberGetAvatarFileName() - gets a file name for the avatar image + +static HANDLE hJabberAvatarsFolder = NULL; +static bool bInitDone = false; + +void CJabberProto::InitCustomFolders( void ) +{ + if ( bInitDone ) + return; + + bInitDone = true; + if ( ServiceExists( MS_FOLDERS_REGISTER_PATH )) { + TCHAR AvatarsFolder[MAX_PATH]; + TCHAR* tmpPath = Utils_ReplaceVarsT( _T("%miranda_avatarcache%")); + mir_sntprintf( AvatarsFolder, SIZEOF( AvatarsFolder ), _T("%s\\Jabber"), tmpPath ); + mir_free(tmpPath); + hJabberAvatarsFolder = FoldersRegisterCustomPathT( m_szModuleName, "Avatars", AvatarsFolder ); // title!!!!!!!!!!! +} } + +void CJabberProto::GetAvatarFileName( HANDLE hContact, TCHAR* pszDest, size_t cbLen ) +{ + size_t tPathLen; + TCHAR* path = ( TCHAR* )alloca( cbLen * sizeof( TCHAR )); + + InitCustomFolders(); + + if ( hJabberAvatarsFolder == NULL || FoldersGetCustomPathT( hJabberAvatarsFolder, path, (int)cbLen, _T(""))) { + TCHAR *tmpPath = Utils_ReplaceVarsT( _T("%miranda_avatarcache%")); + tPathLen = mir_sntprintf( pszDest, cbLen, _T("%s\\Jabber"), tmpPath ); + mir_free(tmpPath); + } + else tPathLen = mir_sntprintf( pszDest, cbLen, _T("%s"), path ); + + DWORD dwAttributes = GetFileAttributes( pszDest ); + if ( dwAttributes == 0xffffffff || ( dwAttributes & FILE_ATTRIBUTE_DIRECTORY ) == 0 ) + JCallService( MS_UTILS_CREATEDIRTREET, 0, ( LPARAM )pszDest ); + + pszDest[ tPathLen++ ] = '\\'; + + char* szFileType = NULL; + switch( JGetByte( hContact, "AvatarType", PA_FORMAT_PNG )) { + case PA_FORMAT_JPEG: szFileType = "jpg"; break; + case PA_FORMAT_PNG: szFileType = "png"; break; + case PA_FORMAT_GIF: szFileType = "gif"; break; + case PA_FORMAT_BMP: szFileType = "bmp"; break; + } + + if ( hContact != NULL ) { + char str[ 256 ]; + DBVARIANT dbv; + if ( !JGetStringUtf( hContact, "jid", &dbv )) { + strncpy( str, dbv.pszVal, sizeof str ); + str[ sizeof(str)-1 ] = 0; + JFreeVariant( &dbv ); + } + else _i64toa(( LONG_PTR )hContact, str, 10 ); + + char* hash = JabberSha1( str ); + mir_sntprintf( pszDest + tPathLen, MAX_PATH - tPathLen, _T(TCHAR_STR_PARAM) _T(".") _T(TCHAR_STR_PARAM), hash, szFileType ); + mir_free( hash ); + } + else if ( m_ThreadInfo != NULL ) { + mir_sntprintf( pszDest + tPathLen, MAX_PATH - tPathLen, _T("%s@") _T(TCHAR_STR_PARAM) _T(" avatar.") _T(TCHAR_STR_PARAM), + m_ThreadInfo->username, m_ThreadInfo->server, szFileType ); + } + else { + DBVARIANT dbv1, dbv2; + BOOL res1 = DBGetContactSettingString( NULL, m_szModuleName, "LoginName", &dbv1 ); + BOOL res2 = DBGetContactSettingString( NULL, m_szModuleName, "LoginServer", &dbv2 ); + mir_sntprintf( pszDest + tPathLen, MAX_PATH - tPathLen, _T(TCHAR_STR_PARAM) _T("@") _T(TCHAR_STR_PARAM) _T(" avatar.") _T(TCHAR_STR_PARAM), + res1 ? "noname" : dbv1.pszVal, + res2 ? m_szModuleName : dbv2.pszVal, + szFileType ); + if (!res1) JFreeVariant( &dbv1 ); + if (!res2) JFreeVariant( &dbv2 ); + } +} + +/////////////////////////////////////////////////////////////////////////////// +// JabberResolveTransportNicks - massive vcard update + +void CJabberProto::ResolveTransportNicks( const TCHAR* jid ) +{ + // Set all contacts to offline + HANDLE hContact = m_ThreadInfo->resolveContact; + if ( hContact == NULL ) + hContact = ( HANDLE ) JCallService( MS_DB_CONTACT_FINDFIRST, 0, 0 ); + + for ( ; hContact != NULL; hContact = ( HANDLE )JCallService( MS_DB_CONTACT_FINDNEXT, ( WPARAM ) hContact, 0 )) { + char* szProto = ( char* )JCallService( MS_PROTO_GETCONTACTBASEPROTO, ( WPARAM ) hContact, 0 ); + if ( lstrcmpA( szProto, m_szModuleName )) + continue; + + if ( !JGetByte( hContact, "IsTransported", 0 )) + continue; + + DBVARIANT dbv, nick; + if ( JGetStringT( hContact, "jid", &dbv )) + continue; + if ( JGetStringT( hContact, "Nick", &nick )) { + JFreeVariant( &dbv ); + continue; + } + + TCHAR* p = _tcschr( dbv.ptszVal, '@' ); + if ( p ) { + *p = 0; + if ( !lstrcmp( jid, p+1 ) && !lstrcmp( dbv.ptszVal, nick.ptszVal )) { + *p = '@'; + m_ThreadInfo->resolveID = SendGetVcard( dbv.ptszVal ); + m_ThreadInfo->resolveContact = hContact; + JFreeVariant( &dbv ); + JFreeVariant( &nick ); + return; + } } + + JFreeVariant( &dbv ); + JFreeVariant( &nick ); + } + + m_ThreadInfo->resolveID = -1; + m_ThreadInfo->resolveContact = NULL; +} + +/////////////////////////////////////////////////////////////////////////////// +// JabberSetServerStatus() + +void CJabberProto::SetServerStatus( int iNewStatus ) +{ + if ( !m_bJabberOnline ) + return; + + // change status + int oldStatus = m_iStatus; + switch ( iNewStatus ) { + case ID_STATUS_ONLINE: + case ID_STATUS_NA: + case ID_STATUS_FREECHAT: + case ID_STATUS_INVISIBLE: + m_iStatus = iNewStatus; + break; + case ID_STATUS_AWAY: + case ID_STATUS_ONTHEPHONE: + case ID_STATUS_OUTTOLUNCH: + m_iStatus = ID_STATUS_AWAY; + break; + case ID_STATUS_DND: + case ID_STATUS_OCCUPIED: + m_iStatus = ID_STATUS_DND; + break; + default: + return; + } + + if ( m_iStatus == oldStatus ) + return; + + // send presence update + SendPresence( m_iStatus, true ); + JSendBroadcast( NULL, ACKTYPE_STATUS, ACKRESULT_SUCCESS, ( HANDLE ) oldStatus, m_iStatus ); +} + +// Process a string, and double all % characters, according to chat.dll's restrictions +// Returns a pointer to the new string (old one is not freed) +TCHAR* EscapeChatTags(TCHAR* pszText) +{ + int nChars = 0; + for ( TCHAR* p = pszText; ( p = _tcschr( p, '%' )) != NULL; p++ ) + nChars++; + + if ( nChars == 0 ) + return mir_tstrdup( pszText ); + + TCHAR* pszNewText = (TCHAR*)mir_alloc( sizeof(TCHAR)*(_tcslen( pszText ) + 1 + nChars )), *s, *d; + if ( pszNewText == NULL ) + return mir_tstrdup( pszText ); + + for ( s = pszText, d = pszNewText; *s; s++ ) { + if ( *s == '%' ) + *d++ = '%'; + *d++ = *s; + } + *d = 0; + return pszNewText; +} + +TCHAR* UnEscapeChatTags(TCHAR* str_in) +{ + TCHAR* s = str_in, *d = str_in; + while ( *s ) { + if ( *s == '%' && s[1] == '%' ) + s++; + *d++ = *s++; + } + *d = 0; + return str_in; +} + +////////////////////////////////////////////////////////////////////////// +// update MirVer with data for active resource + +struct +{ + TCHAR *node; + TCHAR *name; +} +static sttCapsNodeToName_Map[] = +{ + { _T("http://miranda-im.org"), _T("Miranda IM Jabber") }, + { _T("http://www.google.com"), _T("GTalk") }, + { _T("http://mail.google.com"), _T("GMail") }, + { _T("http://talk.google.com/xmpp/bot"), _T("GTalk Bot") }, + { _T("http://www.android.com"), _T("Android") }, +}; + +void CJabberProto::UpdateMirVer(JABBER_LIST_ITEM *item) +{ + HANDLE hContact = HContactFromJID(item->jid); + if (!hContact) + return; + + Log("JabberUpdateMirVer: for jid " TCHAR_STR_PARAM, item->jid); + + int resource = -1; + if (item->resourceMode == RSMODE_LASTSEEN) + resource = item->lastSeenResource; + else if (item->resourceMode == RSMODE_MANUAL) + resource = item->manualResource; + if ((resource < 0) || (resource >= item->resourceCount)) + return; + + UpdateMirVer( hContact, &item->resource[resource] ); +} + +void CJabberProto::FormatMirVer(JABBER_RESOURCE_STATUS *resource, TCHAR *buf, int bufSize) +{ + if ( !buf || !bufSize ) return; + buf[ 0 ] = _T('\0'); + if ( !resource ) return; + + // jabber:iq:version info requested and exists? + if ( resource->dwVersionRequestTime && resource->software ) { + Log("JabberUpdateMirVer: for iq:version rc " TCHAR_STR_PARAM ": " TCHAR_STR_PARAM, resource->resourceName, resource->software); + if ( !resource->version || _tcsstr(resource->software, resource->version)) + lstrcpyn(buf, resource->software, bufSize); + else + mir_sntprintf(buf, bufSize, _T("%s %s"), resource->software, resource->version); + } + // no version info and no caps info? set MirVer = resource name + else if ( !resource->szCapsNode || !resource->szCapsVer ) { + Log("JabberUpdateMirVer: for rc " TCHAR_STR_PARAM ": " TCHAR_STR_PARAM, resource->resourceName, resource->resourceName); + if ( resource->resourceName ) + lstrcpyn(buf, resource->resourceName, bufSize); + } + // XEP-0115 caps mode + else { + Log("JabberUpdateMirVer: for rc " TCHAR_STR_PARAM ": " TCHAR_STR_PARAM "#" TCHAR_STR_PARAM, resource->resourceName, resource->szCapsNode, resource->szCapsVer); + + int i; + + // search through known software list + for (i = 0; i < SIZEOF(sttCapsNodeToName_Map); ++i) + if ( _tcsstr( resource->szCapsNode, sttCapsNodeToName_Map[i].node ) ) + { + mir_sntprintf( buf, bufSize, _T("%s %s"), sttCapsNodeToName_Map[i].name, resource->szCapsVer ); + break; + } + + // unknown software + if (i == SIZEOF(sttCapsNodeToName_Map)) + mir_sntprintf( buf, bufSize, _T("%s %s"), resource->szCapsNode, resource->szCapsVer ); + } + + // attach additional info for fingerprint plguin + if (resource->resourceName && !_tcsstr(buf, resource->resourceName)) + { + if (_tcsstr(buf, _T("Miranda IM")) || m_options.ShowForeignResourceInMirVer ) + { + int offset = lstrlen(buf); + mir_sntprintf(buf + offset, bufSize - offset, _T(" [%s]"), resource->resourceName); + } + } + + if (resource->szCapsExt && _tcsstr(resource->szCapsExt, _T(JABBER_EXT_SECUREIM)) && !_tcsstr(buf, _T("(SecureIM)"))) + { + int offset = lstrlen(buf); + mir_sntprintf(buf + offset, bufSize - offset, _T(" (SecureIM)")); + } +} + + +void CJabberProto::UpdateMirVer(HANDLE hContact, JABBER_RESOURCE_STATUS *resource) +{ + TCHAR szMirVer[ 512 ]; + FormatMirVer(resource, szMirVer, SIZEOF(szMirVer)); + if ( szMirVer[0] ) + JSetStringT( hContact, "MirVer", szMirVer ); + else + JDeleteSetting( hContact, "MirVer" ); + + DBVARIANT dbv; + if ( !JGetStringT( hContact, "jid", &dbv )) { + TCHAR szFullJid[ JABBER_MAX_JID_LEN ]; + if ( resource->resourceName ) + mir_sntprintf( szFullJid, SIZEOF( szFullJid ), _T("%s/%s"), dbv.ptszVal, resource->resourceName ); + else + lstrcpyn( szFullJid, dbv.ptszVal, SIZEOF(szFullJid) ); + JSetStringT( hContact, DBSETTING_DISPLAY_UID, szFullJid ); + JFreeVariant( &dbv ); + } +} + +void CJabberProto::UpdateSubscriptionInfo(HANDLE hContact, JABBER_LIST_ITEM *item) +{ + switch (item->subscription) + { + case SUB_TO: + JSetStringT(hContact, "SubscriptionText", TranslateT("To")); + JSetString(hContact, "Subscription", "to"); + JSetByte(hContact, "Auth", 0); + JSetByte(hContact, "Grant", 1); + break; + case SUB_FROM: + JSetStringT(hContact, "SubscriptionText", TranslateT("From")); + JSetString(hContact, "Subscription", "from"); + JSetByte(hContact, "Auth", 1); + JSetByte(hContact, "Grant", 0); + break; + case SUB_BOTH: + JSetStringT(hContact, "SubscriptionText", TranslateT("Both")); + JSetString(hContact, "Subscription", "both"); + JSetByte(hContact, "Auth", 0); + JSetByte(hContact, "Grant", 0); + break; + case SUB_NONE: + JSetStringT(hContact, "SubscriptionText", TranslateT("None")); + JSetString(hContact, "Subscription", "none"); + JSetByte(hContact, "Auth", 1); + JSetByte(hContact, "Grant", 1); + break; + } +} + +void CJabberProto::SetContactOfflineStatus( HANDLE hContact ) +{ + if ( JGetWord( hContact, "Status", ID_STATUS_OFFLINE ) != ID_STATUS_OFFLINE ) + JSetWord( hContact, "Status", ID_STATUS_OFFLINE ); + + JDeleteSetting( hContact, DBSETTING_XSTATUSID ); + JDeleteSetting( hContact, DBSETTING_XSTATUSNAME ); + JDeleteSetting( hContact, DBSETTING_XSTATUSMSG ); + JDeleteSetting( hContact, DBSETTING_DISPLAY_UID ); + + ResetAdvStatus( hContact, ADVSTATUS_MOOD ); + ResetAdvStatus( hContact, ADVSTATUS_TUNE ); + + //JabberUpdateContactExtraIcon(hContact); +} + +void CJabberProto::InitPopups(void) +{ + TCHAR desc[256]; + char name[256]; + + POPUPCLASS ppc = {0}; + ppc.cbSize = sizeof(ppc); + ppc.flags = PCF_TCHAR; + + ppc.ptszDescription = desc; + ppc.pszName = name; + ppc.hIcon = LoadIconEx("main"); + ppc.colorBack = RGB(191, 0, 0); //Red + ppc.colorText = RGB(255, 245, 225); //Yellow + ppc.iSeconds = 60; + mir_sntprintf(desc, SIZEOF(desc), _T("%s %s"), m_tszUserName, TranslateT("Errors")); + mir_snprintf(name, SIZEOF(name), "%s_%s", m_szModuleName, "Error"); + + JCallService(MS_POPUP_REGISTERCLASS, 0, (WPARAM)&ppc); +} + +void CJabberProto::MsgPopup(HANDLE hContact, const TCHAR *szMsg, const TCHAR *szTitle) +{ + if (ServiceExists(MS_POPUP_ADDPOPUPCLASS)) { + char name[256]; + + POPUPDATACLASS ppd = { sizeof(ppd) }; + ppd.ptszTitle = szTitle; + ppd.ptszText = szMsg; + ppd.pszClassName = name; + ppd.hContact = hContact; + mir_snprintf(name, SIZEOF(name), "%s_%s", m_szModuleName, "Error"); + + JCallService(MS_POPUP_ADDPOPUPCLASS, 0, (LPARAM)&ppd); + } else { + DWORD mtype = MB_OK | MB_SETFOREGROUND | MB_ICONSTOP; + MessageBox(NULL, szMsg, szTitle, mtype); + } +} -- cgit v1.2.3