summaryrefslogtreecommitdiff
path: root/protocols/JabberG/jabber_misc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/JabberG/jabber_misc.cpp')
-rw-r--r--protocols/JabberG/jabber_misc.cpp648
1 files changed, 648 insertions, 0 deletions
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 <m_popup.h>
+#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);
+ }
+}